It is due to the time it takes for your keyboard to start autorepeat a pressed key, it is easy to fix this, by re-calling the input function via
. There is one new parameter,
, lower values means quicker. You can get a lot of different behaviour with this, you'll need to tweak until you find something suitable.
Code: Select all
class ButtonsToAxisAccAndDecay extends _UCR.Classes.Plugin {
Type := "Remapper (Buttons To Axis) (Acceleration and Decay)"
Description := "Remaps two InputButtons to one OutputAxis - Added acceleration and decay options"
AxisButtonStates := [0,0]
DeflectionValues := []
IncrementalMode := 0
Init(){
iow := 125
Gui, Add, GroupBox, Center xm ym w270 h70 section, Input Buttons
Gui, Add, Text, % "Center xs+5 yp+15 w" iow, Low
Gui, Add, Text, % "Center x+10 w" iow " yp", High
this.AddControl("InputButton", "IB1", 0, this.ButtonInput.Bind(this, 1), " xs+5 yp+15")
this.AddControl("InputButton", "IB2", 0, this.ButtonInput.Bind(this, 2), "x+10 yp")
Gui, Add, GroupBox, Center x285 ym w120 h70 section, Settings
Gui, Add, Text, % "Center xs+5 yp+15 w110", Deflection `%
this.AddControl("Edit", "DeflectionAmount", this.DeflectionChanged.Bind(this), "xs+5 w110 yp+15 center", 100)
this.AddControl("CheckBox", "IncrementalMode", this.IncrementalModeChanged.Bind(this), "xp y+3", "Incremental Mode")
Gui, Add, GroupBox, Center x410 ym w260 h70 section, Output Axis
Gui, Add, Text, % "Center xs+5 yp+15 w" iow, Axis
Gui, Add, Text, % "Center x+2 w" iow " yp", Preview
this.AddControl("OutputAxis", "OA1", 0, "xs+5 yp+15")
Gui, Add, Slider, % "hwndhwnd x+2 yp", 50
this.hSlider := hwnd
; Acceleration settings
Gui, Add, GroupBox, Center xm y80 w325 h45 section, Acceleration
this.AddControl("CheckBox", "accMode", this.AccModeChanged.Bind(this), "xp+4 yp+20", "Enable")
Gui, Add, Text, % "Center x+3 hwndinertiaText", % "Inertia:"
this.inertiaText:=inertiaText
this.AddControl("Edit", "inertiaEdit", this.inertiaChanged.Bind(this), "x+3 yp-3 w20 center number disabled", 3)
Gui, Add, Text, % "Center x+3 yp+3 hwndrateText", % "Rate:"
this.rateText:=rateText
this.AddControl("Edit", "incrementRateEdit", this.incrementRateChanged.Bind(this), "x+3 yp-3 w25 center number disabled", 30)
this.AddControl("CheckBox", "accCapCB", this.AccCapCBChanged.Bind(this), "x+3 yp+3 disabled", "Cap")
this.AddControl("Edit", "accCapEdit", this.AccCapChanged.Bind(this), "x+3 yp-3 w20 center number disabled", 5)
Gui, Add, Text, % "Center x+3 yp+3 hwndresetText", % "Timeout:"
this.resetText:=resetText
this.AddControl("Edit", "resetEdit", this.resetChanged.Bind(this), "x+3 yp-3 w30 center number disabled", 150)
this.tic:=0, this.acc:=0, pAccdir:=0, this.inertiaCtr:=0 ; Acceleration handling parameters
; Decay settings
Gui, Add, GroupBox, Center x+5 y80 w340 h45 section, Decay
this.AddControl("CheckBox", "decayMode", this.DecayModeChanged.Bind(this), "xs+10 yp+20", "Enable")
Gui, Add, Text, % "Center x+5 hwnddecayRateText", % "Rate:"
this.decayRateText:=decayRateText
this.AddControl("Edit", "decayRateEdit", this.DecayRateChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 25)
Gui, Add, Text, % "Center x+5 yp+2 hwnddecayStepText", % "Step:"
this.decayStepText:=decayStepText
this.AddControl("Edit", "decayStepEdit", this.DecayStepChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 3)
Gui, Add, Text, % "Center x+5 yp+3 hwnddecayDelayText", % "Delay:"
this.decayDelayText:=decayDelayText
this.AddControl("Edit", "decayDelayEdit", this.DecayDelayChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 200)
this.AddControl("CheckBox", "linearDecayCB", this.LinearDecayCBChanged.Bind(this), "x+5 yp+4 checked disabled", "Linear")
}
OnClose(){
if (this.decayTimer){
timerFunc:=this.decayTimer
try
SetTimer, % timerFunc, delete
this.decayTimer:=""
}
if (this.incrementTimer){
timerFunc:=this.incrementTimer
try
SetTimer, % timerFunc, delete
this.incrementTimer:=""
}
base.OnClose() ; ?
}
DeflectionChanged(pc){
value := 50 * (pc / 100)
this.IncrementalDeflectionValues[1] := value * -1
this.IncrementalDeflectionValues[2] := value
this.DeflectionValues[1] := UCR.Libraries.StickOps.InternalToAHK(value * -1)
this.DeflectionValues[2] := UCR.Libraries.StickOps.InternalToAHK(value)
}
IncrementalModeChanged(state){
this.IncrementalMode := state
}
; Decay settings functions
DecayModeChanged(state){
this.decayMode:=state
if (state && !this.decayTimer)
this.decayTimer:=ObjBindMethod(this,"decay")
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.linearDecayCB.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.decayRateEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.decayRateText
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.decayStepEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.decayStepText
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.decayDelayEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.decayDelayText
}
LinearDecayCBChanged(state){
this.linDecay:=state
}
DecayRateChanged(val){
this.decayRate:=val
}
DecayStepChanged(val){
this.decayStep:=val
}
DecayDelayChanged(val){
this.decayDelay:=val?val:1 ; Not sure 0 is a good idea, test.
}
; Acceleration settings functions
AccModeChanged(state){
this.accMode := state
; This is a bit over the top I guess...
GuiControl, % state && this.capAccEnabled ? "Enable" : "Disable", % this.GuiControls.accCapEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.accCapCB.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.inertiaEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.inertiaText
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.incrementRateEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.rateText
GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.resetEdit.hwnd
GuiControl, % state ? "Enable" : "Disable", % this.resetText
}
incrementRateChanged(value){
return this.incrementRate:=value
}
AccCapCBChanged(state){
this.capAccEnabled:=state
GuiControl, % state && this.accMode ? "Enable" : "Disable", % this.GuiControls.accCapEdit.hwnd
}
AccCapChanged(val){
this.accCapVal:=val
}
inertiaChanged(val){
this.inertiaChanged:=true
this.inertiaVal:=val
}
resetChanged(val){
this.timeout:=val
}
; End acceleration funtionc
; One of the input buttons was pressed or released
ButtonInput(direction, value){
;OutputDebug % "UCR| Axis: " axis ", Direction: " direction ", value: " value
if (!this.IncrementalMode && this.AxisButtonStates[direction] = value)
return ; filter repeats if not in Incremental Mode
if (this.IncrementalMode && !value && this.incrementTimer)
{
fn:=this.incrementTimer
SetTimer, % fn, Delete
this.incrementTimer:=""
}
this.AxisButtonStates[direction] := value
if (this.IncrementalMode){
; Incremental Mode - alter current axis by deflection value on press
if (!value){
this.decayMode ? this.setDecayTimer() : ""
return ; Do nothing on release
}
if (this.accMode) {
this.inertiaChanged ? (this.inertiaChanged:=false, this.inertiaCtr:=this.inertiaVal) : ""
this.inertiaCtr && this.pAccdir==direction ? --this.inertiaCtr : this.inertiaCtr:=this.inertiaVal
A_TickCount-this.tic < this.timeout && this.pAccdir==direction ? (this.capAccEnabled ? (this.acc<this.accCapVal && !this.inertiaCtr ? ++this.acc : "") : !this.inertiaCtr ? ++this.acc : "" ) : this.acc:=0 ; Determine acceleration
}
out := this.IOControls.OA1.Get() + this.IncrementalDeflectionValues[direction] + (direction==1?-1:1)*this.acc
this.accMode ? (this.tic:=A_TickCount, this.pAccdir:=direction) : this.acc:=0 ; Update acceleration parameters
this.decayMode ? this.stopDecayTimer() : ""
} else {
; Normal Mode - Set axis to deflection value on press, set to middle on release
if (this.AxisButtonStates[1] == this.AxisButtonStates[2]){
if (this.decayMode) {
this.setDecayTimer()
return
}
else {
out:=50
}
} else {
this.decayMode ? this.stopDecayTimer() : ""
if (this.AxisButtonStates[1]){
out := this.DeflectionValues[1]
} else {
out := this.DeflectionValues[2]
}
}
}
this.IOControls.OA1.Set(out)
GuiControl, , % this.hSlider, % out
if (this.IncrementalMode && value && !this.incrementTimer)
{
fn:=ObjBindMethod(this,"ButtonInput",direction,value)
this.incrementTimer:=fn
SetTimer, % fn, % this.incrementRate
}
}
stopDecayTimer(){
if !this.timerIsRunning
return
this.timerIsRunning:=0
timerFunc:=this.decayTimer
try
SetTimer, % timerFunc , Delete
}
setDecayTimer(){
this.startDecay:=1
this.timerIsRunning:=1
timerFunc:=this.decayTimer
SetTimer, % timerFunc, % -this.decayDelay
}
decay(){
static nonLinearFactor:=1.3 ; Internal setting, could be optional if one even wants non linear decay. Set <1 for decreasing rate, >1 for increasing.
state:=this.IOControls.OA1.Get()
dir:=this.calcDirection(state)
if (this.startDecay) {
this.pStep:=this.decayStep, this.pDir:=dir, this.startDecay:=0 ; Reset vars
}
step:=state+dir*(this.linDecay ? this.decayStep : abs(this.pStep)*nonLinearFactor + (nonLinearFactor<1?1:0)) ; abs(pStep)*nonLinearFactor+(?:) is the nonLinearFactor formula, it is just taken out of the blue for testing.
out:= (abs(state-50)<0.01 || dir!=this.pDir) ? out:=50 : step
out := this.calcDirection(out)!=dir ? 50 : out ; guard against overshoot
this.pStep:=step-state
SetTimer,, % out==50 && ((this.timerIsRunning:=0) || true) ? "Off" : this.decayRate
this.IOControls.OA1.Set(out)
GuiControl, , % this.hSlider, % out
this.pDir:=dir
}
calcDirection(state){
return (state<50)-(state>=50)
}
}
For reference, with these settings, the behaviour of these two plugins are quite similar,