6 changed files with 374 additions and 1 deletions
@ -0,0 +1,39 @@ |
|||||
|
; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey |
||||
|
; https://www.autohotkey.com |
||||
|
|
||||
|
; |
||||
|
; Front Matter |
||||
|
; |
||||
|
|
||||
|
; Include general library |
||||
|
#Include ../lib/Prelude.ahk |
||||
|
|
||||
|
; Include XInput library |
||||
|
#Include ../thirdparty/XInput/XInput.ahk |
||||
|
|
||||
|
; Only do hotkeys if relevant window is |
||||
|
;#If WinActive("Dark Souls III") |
||||
|
|
||||
|
; |
||||
|
; Hotkeys |
||||
|
; |
||||
|
XInput_Init() |
||||
|
|
||||
|
PrevState := 0 |
||||
|
Loop { |
||||
|
State := XInput_GetState(0) |
||||
|
if ( State.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ) { |
||||
|
if (PrevState == 0) { |
||||
|
Send {LButton down} |
||||
|
Send {w down} |
||||
|
PrevState := 1 |
||||
|
} |
||||
|
} else { |
||||
|
if (PrevState == 1) { |
||||
|
Send {LButton up} |
||||
|
Send {w up} |
||||
|
PrevState := 0 |
||||
|
} |
||||
|
} |
||||
|
Sleep 50 |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
; Include general library |
||||
|
#Include ../lib/Prelude.ahk |
||||
|
|
||||
|
; Don't show a tray icon |
||||
|
#NoTrayIcon |
||||
|
|
||||
|
; Which device the microphone is |
||||
|
; Use third party AudioFinder script to figure this out |
||||
|
Device := 9 |
||||
|
|
||||
|
MuteMic() { |
||||
|
local MM |
||||
|
SoundSet, +1, MASTER, MUTE, %Device% |
||||
|
If ( ErrorLevel != 0 ) { |
||||
|
MsgBox, Error: %ErrorLevel% |
||||
|
} |
||||
|
SoundGet, MM, MASTER, MUTE, %Device% |
||||
|
#Persistent |
||||
|
ToolTip, % (MM == "On" ? "Microphone muted" : "Microphone online") |
||||
|
SetTimer, RemoveMuteMicTooltip, 700 |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
RemoveMuteMicTooltip: |
||||
|
SetTimer, RemoveMuteMicTooltip, Off |
||||
|
ToolTip |
||||
|
return |
||||
|
|
||||
|
; |
||||
|
; Hotkey |
||||
|
; |
||||
|
|
||||
|
^F12::MuteMic() |
@ -0,0 +1,67 @@ |
|||||
|
SetBatchLines -1 |
||||
|
SplashTextOn,,, Gathering Soundcard Info... |
||||
|
|
||||
|
; Most of the pure numbers below probably don't exist in any mixer, but they're queried for completeness. |
||||
|
; The numbers correspond to the following items (in order): CUSTOM, BOOLEANMETER, SIGNEDMETER, PEAKMETER, |
||||
|
; UNSIGNEDMETER, BOOLEAN, BUTTON, DECIBELS, SIGNED, UNSIGNED, PERCENT, SLIDER, FADER, SINGLESELECT, MUX, |
||||
|
; MULTIPLESELECT, MIXER, MICROTIME, MILLITIME |
||||
|
ControlTypes := "VOLUME,ONOFF,MUTE,MONO,LOUDNESS,STEREOENH,BASSBOOST,PAN,QSOUNDPAN,BASS,TREBLE,EQUALIZER,0x00000000, 0x10010000,0x10020000,0x10020001,0x10030000,0x20010000,0x21010000,0x30040000,0x30020000,0x30030000,0x30050000,0x40020000,0x50030000,0x70010000,0x70010001,0x71010000,0x71010001,0x60030000,0x61030000" |
||||
|
|
||||
|
ComponentTypes := "MASTER,HEADPHONES,DIGITAL,LINE,MICROPHONE,SYNTH,CD,TELEPHONE,PCSPEAKER,WAVE,AUX,ANALOG,N/A" |
||||
|
|
||||
|
; Create a ListView and prepare for the main loop: |
||||
|
Gui, Add, ListView, w400 h400 vMyListView, Component Type|Control Type|Setting|Mixer |
||||
|
LV_ModifyCol(4, "Integer") |
||||
|
SetFormat, Float, 0.2 ; Limit number of decimal places in percentages to two. |
||||
|
|
||||
|
Loop ; For each mixer number that exists in the system, query its capabilities. |
||||
|
{ |
||||
|
CurrMixer := A_Index |
||||
|
SoundGet, Setting,,, %CurrMixer% |
||||
|
if (ErrorLevel = "Can't Open Specified Mixer") ; Any error other than this indicates that the mixer exists. |
||||
|
break |
||||
|
|
||||
|
; For each component type that exists in this mixer, query its instances and control types: |
||||
|
Loop, parse, ComponentTypes, `, |
||||
|
{ |
||||
|
CurrComponent := A_LoopField |
||||
|
; First check if this component type even exists in the mixer: |
||||
|
SoundGet, Setting, %CurrComponent%,, %CurrMixer% |
||||
|
if (ErrorLevel = "Mixer Doesn't Support This Component Type") |
||||
|
continue ; Start a new iteration to move on to the next component type. |
||||
|
Loop ; For each instance of this component type, query its control types. |
||||
|
{ |
||||
|
CurrInstance := A_Index |
||||
|
; First check if this instance of this instance even exists in the mixer: |
||||
|
SoundGet, Setting, %CurrComponent%:%CurrInstance%,, %CurrMixer% |
||||
|
; Checking for both of the following errors allows this script to run on older versions: |
||||
|
if ErrorLevel in Mixer Doesn't Have That Many of That Component Type,Invalid Control Type or Component Type |
||||
|
break ; No more instances of this component type. |
||||
|
; Get the current setting of each control type that exists in this instance of this component: |
||||
|
Loop, parse, ControlTypes, `, |
||||
|
{ |
||||
|
CurrControl := A_LoopField |
||||
|
SoundGet, Setting, %CurrComponent%:%CurrInstance%, %CurrControl%, %CurrMixer% |
||||
|
; Checking for both of the following errors allows this script to run on older versions: |
||||
|
if ErrorLevel in Component Doesn't Support This Control Type,Invalid Control Type or Component Type |
||||
|
continue |
||||
|
if ErrorLevel ; Some other error, which is unexpected so show it in the results. |
||||
|
Setting := ErrorLevel |
||||
|
ComponentString := CurrComponent |
||||
|
if (CurrInstance > 1) |
||||
|
ComponentString := ComponentString ":" CurrInstance |
||||
|
LV_Add("", ComponentString, CurrControl, Setting, CurrMixer) |
||||
|
} ; For each control type. |
||||
|
} ; For each component instance. |
||||
|
} ; For each component type. |
||||
|
} ; For each mixer. |
||||
|
|
||||
|
Loop % LV_GetCount("Col") ; Auto-size each column to fit its contents. |
||||
|
LV_ModifyCol(A_Index, "AutoHdr") |
||||
|
|
||||
|
SplashTextOff |
||||
|
Gui, Show |
||||
|
return |
||||
|
|
||||
|
GuiClose: |
||||
|
ExitApp |
@ -0,0 +1,223 @@ |
|||||
|
/* XInput by Lexikos |
||||
|
* Requires AutoHotkey 1.1+. |
||||
|
*/ |
||||
|
|
||||
|
/* |
||||
|
Function: XInput_Init |
||||
|
|
||||
|
Initializes XInput.ahk with the given XInput DLL. |
||||
|
|
||||
|
Parameters: |
||||
|
dll - The path or name of the XInput DLL to load. |
||||
|
*/ |
||||
|
XInput_Init(dll:="") |
||||
|
{ |
||||
|
global |
||||
|
if _XInput_hm |
||||
|
return |
||||
|
|
||||
|
;======== CONSTANTS DEFINED IN XINPUT.H ======== |
||||
|
|
||||
|
; NOTE: These are based on my outdated copy of the DirectX SDK. |
||||
|
; Newer versions of XInput may require additional constants. |
||||
|
|
||||
|
; Device types available in XINPUT_CAPABILITIES |
||||
|
XINPUT_DEVTYPE_GAMEPAD := 0x01 |
||||
|
|
||||
|
; Device subtypes available in XINPUT_CAPABILITIES |
||||
|
XINPUT_DEVSUBTYPE_GAMEPAD := 0x01 |
||||
|
|
||||
|
; Flags for XINPUT_CAPABILITIES |
||||
|
XINPUT_CAPS_VOICE_SUPPORTED := 0x0004 |
||||
|
|
||||
|
; Constants for gamepad buttons |
||||
|
XINPUT_GAMEPAD_DPAD_UP := 0x0001 |
||||
|
XINPUT_GAMEPAD_DPAD_DOWN := 0x0002 |
||||
|
XINPUT_GAMEPAD_DPAD_LEFT := 0x0004 |
||||
|
XINPUT_GAMEPAD_DPAD_RIGHT := 0x0008 |
||||
|
XINPUT_GAMEPAD_START := 0x0010 |
||||
|
XINPUT_GAMEPAD_BACK := 0x0020 |
||||
|
XINPUT_GAMEPAD_LEFT_THUMB := 0x0040 |
||||
|
XINPUT_GAMEPAD_RIGHT_THUMB := 0x0080 |
||||
|
XINPUT_GAMEPAD_LEFT_SHOULDER := 0x0100 |
||||
|
XINPUT_GAMEPAD_RIGHT_SHOULDER := 0x0200 |
||||
|
XINPUT_GAMEPAD_GUIDE := 0x0400 |
||||
|
XINPUT_GAMEPAD_A := 0x1000 |
||||
|
XINPUT_GAMEPAD_B := 0x2000 |
||||
|
XINPUT_GAMEPAD_X := 0x4000 |
||||
|
XINPUT_GAMEPAD_Y := 0x8000 |
||||
|
|
||||
|
; Gamepad thresholds |
||||
|
XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE := 7849 |
||||
|
XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE := 8689 |
||||
|
XINPUT_GAMEPAD_TRIGGER_THRESHOLD := 30 |
||||
|
|
||||
|
; Flags to pass to XInputGetCapabilities |
||||
|
XINPUT_FLAG_GAMEPAD := 0x00000001 |
||||
|
|
||||
|
;=============== END CONSTANTS ================= |
||||
|
|
||||
|
if (dll = "") |
||||
|
Loop %A_WinDir%\System32\XInput1_*.dll |
||||
|
dll := A_LoopFileName |
||||
|
if (dll = "") |
||||
|
dll := "XInput1_3.dll" |
||||
|
|
||||
|
_XInput_hm := DllCall("LoadLibrary" ,"str",dll ,"ptr") |
||||
|
|
||||
|
if !_XInput_hm |
||||
|
throw Exception("Failed to initialize XInput: " dll " not found.") |
||||
|
|
||||
|
(_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"ptr",100 ,"ptr")) |
||||
|
|| (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetState" ,"ptr")) |
||||
|
_XInput_SetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputSetState" ,"ptr") |
||||
|
_XInput_GetCapabilities := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetCapabilities" ,"ptr") |
||||
|
|
||||
|
if !(_XInput_GetState && _XInput_SetState && _XInput_GetCapabilities) |
||||
|
{ |
||||
|
XInput_Term() |
||||
|
throw Exception("Failed to initialize XInput: function not found.") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
Function: XInput_GetState |
||||
|
|
||||
|
Retrieves the current state of the specified controller. |
||||
|
|
||||
|
Parameters: |
||||
|
UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. |
||||
|
|
||||
|
Returns: |
||||
|
The current state of the controller as an associative array. |
||||
|
|
||||
|
ErrorLevel: |
||||
|
If the function succeeds, ErrorLevel is ERROR_SUCCESS (zero). |
||||
|
If the controller is not connected, ErrorLevel is ERROR_DEVICE_NOT_CONNECTED (1167). |
||||
|
If the function fails, ErrorLevel is an error code defined in Winerror.h. |
||||
|
http://msdn.microsoft.com/en-us/library/ms681381.aspx |
||||
|
|
||||
|
Remarks: |
||||
|
XInput.dll returns controller state as a binary structure: |
||||
|
http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_state |
||||
|
http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_gamepad |
||||
|
*/ |
||||
|
XInput_GetState(UserIndex) |
||||
|
{ |
||||
|
global _XInput_GetState |
||||
|
|
||||
|
VarSetCapacity(xiState,16) |
||||
|
|
||||
|
if ErrorLevel := DllCall(_XInput_GetState ,"uint",UserIndex ,"uint",&xiState) |
||||
|
return 0 |
||||
|
|
||||
|
return { |
||||
|
(Join, |
||||
|
dwPacketNumber: NumGet(xiState, 0, "UInt") |
||||
|
wButtons: NumGet(xiState, 4, "UShort") |
||||
|
bLeftTrigger: NumGet(xiState, 6, "UChar") |
||||
|
bRightTrigger: NumGet(xiState, 7, "UChar") |
||||
|
sThumbLX: NumGet(xiState, 8, "Short") |
||||
|
sThumbLY: NumGet(xiState, 10, "Short") |
||||
|
sThumbRX: NumGet(xiState, 12, "Short") |
||||
|
sThumbRY: NumGet(xiState, 14, "Short") |
||||
|
)} |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
Function: XInput_SetState |
||||
|
|
||||
|
Sends data to a connected controller. This function is used to activate the vibration |
||||
|
function of a controller. |
||||
|
|
||||
|
Parameters: |
||||
|
UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. |
||||
|
LeftMotorSpeed - [in] Speed of the left motor, between 0 and 65535. |
||||
|
RightMotorSpeed - [in] Speed of the right motor, between 0 and 65535. |
||||
|
|
||||
|
Returns: |
||||
|
If the function succeeds, the return value is 0 (ERROR_SUCCESS). |
||||
|
If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED). |
||||
|
If the function fails, the return value is an error code defined in Winerror.h. |
||||
|
http://msdn.microsoft.com/en-us/library/ms681381.aspx |
||||
|
|
||||
|
Remarks: |
||||
|
The left motor is the low-frequency rumble motor. The right motor is the |
||||
|
high-frequency rumble motor. The two motors are not the same, and they create |
||||
|
different vibration effects. |
||||
|
*/ |
||||
|
XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed) |
||||
|
{ |
||||
|
global _XInput_SetState |
||||
|
return DllCall(_XInput_SetState ,"uint",UserIndex ,"uint*",LeftMotorSpeed|RightMotorSpeed<<16) |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
Function: XInput_GetCapabilities |
||||
|
|
||||
|
Retrieves the capabilities and features of a connected controller. |
||||
|
|
||||
|
Parameters: |
||||
|
UserIndex - [in] Index of the user's controller. Can be a value in the range 0–3. |
||||
|
Flags - [in] Input flags that identify the controller type. |
||||
|
0 - All controllers. |
||||
|
1 - XINPUT_FLAG_GAMEPAD: Xbox 360 Controllers only. |
||||
|
|
||||
|
Returns: |
||||
|
The controller capabilities, as an associative array. |
||||
|
|
||||
|
ErrorLevel: |
||||
|
If the function succeeds, ErrorLevel is 0 (ERROR_SUCCESS). |
||||
|
If the controller is not connected, ErrorLevel is 1167 (ERROR_DEVICE_NOT_CONNECTED). |
||||
|
If the function fails, ErrorLevel is an error code defined in Winerror.h. |
||||
|
http://msdn.microsoft.com/en-us/library/ms681381.aspx |
||||
|
|
||||
|
Remarks: |
||||
|
XInput.dll returns capabilities via a binary structure: |
||||
|
http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_capabilities |
||||
|
*/ |
||||
|
XInput_GetCapabilities(UserIndex, Flags) |
||||
|
{ |
||||
|
global _XInput_GetCapabilities |
||||
|
|
||||
|
VarSetCapacity(xiCaps,20) |
||||
|
|
||||
|
if ErrorLevel := DllCall(_XInput_GetCapabilities ,"uint",UserIndex ,"uint",Flags ,"ptr",&xiCaps) |
||||
|
return 0 |
||||
|
|
||||
|
return, |
||||
|
(Join |
||||
|
{ |
||||
|
Type: NumGet(xiCaps, 0, "UChar"), |
||||
|
SubType: NumGet(xiCaps, 1, "UChar"), |
||||
|
Flags: NumGet(xiCaps, 2, "UShort"), |
||||
|
Gamepad: |
||||
|
{ |
||||
|
wButtons: NumGet(xiCaps, 4, "UShort"), |
||||
|
bLeftTrigger: NumGet(xiCaps, 6, "UChar"), |
||||
|
bRightTrigger: NumGet(xiCaps, 7, "UChar"), |
||||
|
sThumbLX: NumGet(xiCaps, 8, "Short"), |
||||
|
sThumbLY: NumGet(xiCaps, 10, "Short"), |
||||
|
sThumbRX: NumGet(xiCaps, 12, "Short"), |
||||
|
sThumbRY: NumGet(xiCaps, 14, "Short") |
||||
|
}, |
||||
|
Vibration: |
||||
|
{ |
||||
|
wLeftMotorSpeed: NumGet(xiCaps, 16, "UShort"), |
||||
|
wRightMotorSpeed: NumGet(xiCaps, 18, "UShort") |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
Function: XInput_Term |
||||
|
Unloads the previously loaded XInput DLL. |
||||
|
*/ |
||||
|
XInput_Term() { |
||||
|
global |
||||
|
if _XInput_hm |
||||
|
DllCall("FreeLibrary","uint",_XInput_hm), _XInput_hm :=_XInput_GetState :=_XInput_SetState :=_XInput_GetCapabilities :=0 |
||||
|
} |
||||
|
|
||||
|
; TODO: XInputEnable, 'GetBatteryInformation and 'GetKeystroke. |
Loading…
Reference in new issue