Universal Control Remapper (UCR) - v0.1.22 28th Oct 2018

Post gaming related scripts
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

02 Jan 2017, 12:11

Ah. Did you disable the vJoy stick before emulating vXBox? Use the vJoy control panel to turn off the vJoy sticks.
The traditional vJoy (DirectInput) stick always exists, and are typically stick ID 1, whereas if you create a vXBox pad, it adds another device - the traditional vJoy stick is still "plugged in".
So if the game is always taking input from the stick with the lowest ID and which is plugged in, (the vJoy stick is typically ID1, and is always plugged in if not disabled), then creating a vXBox pad will not change that.
vXBox mode in UCR does not require that any vJoy sticks are active, just that vJoy and the SCPVBus is installed. As long as when you configure vXBox as an output in UCR, you hear a system sound and an XBox controller appears in the game controller dialog, you are golden.

You may also want to try PJP JoyIDs (Google it), which will let you switch IDs. If you change the ID of the vXBox pad or some other device to be lower than that of the vJoy stick, the game will probably take input from that.
thieftheodore
Posts: 9
Joined: 31 Dec 2016, 12:39

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

03 Jan 2017, 21:22

evilC wrote:Ah. Did you disable the vJoy stick before emulating vXBox? Use the vJoy control panel to turn off the vJoy sticks.
The traditional vJoy (DirectInput) stick always exists, and are typically stick ID 1, whereas if you create a vXBox pad, it adds another device - the traditional vJoy stick is still "plugged in".
So if the game is always taking input from the stick with the lowest ID and which is plugged in, (the vJoy stick is typically ID1, and is always plugged in if not disabled), then creating a vXBox pad will not change that.
vXBox mode in UCR does not require that any vJoy sticks are active, just that vJoy and the SCPVBus is installed. As long as when you configure vXBox as an output in UCR, you hear a system sound and an XBox controller appears in the game controller dialog, you are golden.

You may also want to try PJP JoyIDs (Google it), which will let you switch IDs. If you change the ID of the vXBox pad or some other device to be lower than that of the vJoy stick, the game will probably take input from that.
Thank you finally managed it to make it work although sometimes the game still getting double input from vxbox and my physical stick and make it not ideal to play action games.
also sometimes the install SCPVBus menu are greyed out
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 05:33

The input doubling issue is something that will be solved sometime soon hopefully.
There is a new tool available called HidGuardian that will let us hide physical sticks from games.

In the meantime, try starting the game with UCR started and vXBox present, but with your physical stick not plugged in.
Once the game has started, plug in your physical stick. This will hopefully force the game to ignore it.
azerty55
Posts: 13
Joined: 28 Nov 2016, 17:34
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 10:18

I have a tricky question, how can I emulate analog stick with keyboard correctly? I mean with analog properties, is it possible?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 10:20

"With analog properties"?
What do you mean, you want to use keyboard for input, and virtual stick for output, but you want it to vary the analog output it makes - ie the axis is not just a fixed value when the key is held?
How would you propose it would behave in practice? Axis deflects more the longer the key is held? What about on release - immediately set axis to middle, or gradually decay?
thieftheodore
Posts: 9
Joined: 31 Dec 2016, 12:39

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 13:21

evilC wrote:In the meantime, try starting the game with UCR started and vXBox present, but with your physical stick not plugged in.
Once the game has started, plug in your physical stick. This will hopefully force the game to ignore it.
unfortunately starting the game first without plugging my physical stick give the same result, the good news is I'm playing turn-based game so the double input doesn't bother me that much (hopefully)
evilC wrote:The input doubling issue is something that will be solved sometime soon hopefully.
There is a new tool available called HidGuardian that will let us hide physical sticks from games.
is this the right HidGuardian?
https://github.com/nefarius/ViGEm/tree/ ... idGuardian
I can't managed to make it work lol, So i'll keep an eye until UCR fixed this issue instead. Good luck for this project, and thank you very much
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 13:24

Yup, that's the right HidGuardian. I have not played with it myself, but I have been in discussion with the author Nefarius and it is definitely the solution we are looking for.
As you can probably see from the checkin dates, it is all still rather new and currently undergoing testing.
Ideally I would like to make it all transparently integrated with UCR, but that may be a while off, I have no idea until I know what will be involved.

I will try and have a play with it soon and see if I can get it to work with UCR.
azerty55
Posts: 13
Joined: 28 Nov 2016, 17:34
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

04 Jan 2017, 18:29

evilC wrote:"With analog properties"?
What do you mean, you want to use keyboard for input, and virtual stick for output, but you want it to vary the analog output it makes - ie the axis is not just a fixed value when the key is held?
How would you propose it would behave in practice? Axis deflects more the longer the key is held? What about on release - immediately set axis to middle, or gradually decay?
In practice is for emulate Xbox 360 controller when keyboard button act like joystick (left stick and right stick)
I map keyboard button axis but in practice is either 0% either 100% so there is no progressive movement like joystick (when I move joystick up on fps the camera go roughly up, no smooth movement)
Im wonder if is it possible to have smooth movement like stick (gradually decay)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

05 Jan 2017, 03:28

azerty55 wrote: I map keyboard button axis but in practice is either 0% either 100% so there is no progressive movement like joystick (when I move joystick up on fps the camera go roughly up, no smooth movement)
Im wonder if is it possible to have smooth movement like stick (gradually decay)
Use ButtonToAxis plugin, check the Incremental mode box, an set Deflection % to eg, 5
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

05 Jan 2017, 05:12

I added some acceleration options to the ButtonToAxis plugin,
Save as ButtonsToAxisAcc.ahk

Code: Select all

class ButtonsToAxisAcc extends _UCR.Classes.Plugin {
	Type := "Remapper (Buttons To Axis) (Acceleration)"
	Description := "Remaps two InputButtons to one OutputAxis - Added acceleration option"
	
	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+0 w" iow " yp", Preview
		this.AddControl("OutputAxis", "OA1", 0, "xs+5 yp+15")
		Gui, Add, Slider, % "hwndhwnd x+0 yp", 50
		this.hSlider := hwnd
		
		; Acceleration settings
		Gui, Add, GroupBox, Center xm y80 w425 h45 section, Acceleration
		this.AddControl("CheckBox", "accMode", this.AccModeChanged.Bind(this), "xs+5 yp+20", "Enable")
		
		Gui, Add, Text, % "Center x+5 hwndinertiaText", % "Inertia:"
		this.inertiaText:=inertiaText
		this.AddControl("Edit", "inertiaEdit", this.inertiaChanged.Bind(this), "x+5 yp-3 w35 center number disabled", 3)
		
		this.AddControl("CheckBox", "accCapCB", this.AccCapCBChanged.Bind(this), "x+5 yp+3 disabled", "Cap acceleration")
		this.AddControl("Edit", "accCapEdit", this.AccCapChanged.Bind(this), "x+5 yp-3 w35 center number disabled", 5)
		
		Gui, Add, Text, % "Center x+5 yp+3 hwndresetText", % "Reset timeout:"
		this.resetText:=resetText
		this.AddControl("Edit", "resetEdit", this.resetChanged.Bind(this), "x+5 yp-3 w35 center number disabled", 150)
		Gui, Add, Text, % "Center x+5 yp+3 hwndmsResetText", % " ms."
		this.msResetText:=msResetText
	}
	
	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
	}
	
	; Acceleration 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.resetEdit.hwnd
		GuiControl, % state ? "Enable" : "Disable", % this.resetText
		GuiControl, % state ? "Enable" : "Disable", % this.msResetText
	}
	
	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
		static tic:=0,acc:=0, pdir:=0, inertia											 ;  Acceleration handling parameters
		if (!this.IncrementalMode && this.AxisButtonStates[direction] = value)
			return	; filter repeats if not in Incremental Mode
		
		this.AxisButtonStates[direction] := value
		
		if (this.IncrementalMode){
			; Incremental Mode - alter current axis by deflection value on press
			if (!value)
				return	; Do nothing on release
			if (this.accMode) {
				this.inertiaChanged ? (this.inertiaChanged:=false, inertia:=this.inertiaVal) : ""
				inertia && pdir==direction ? --inertia : inertia:=this.inertiaVal
				(toc:=A_TickCount-tic) < this.timeout && pdir==direction ? (this.capAccEnabled ? (acc<this.accCapVal && !inertia ? ++acc : "") : !inertia ? ++acc : "" ) : acc:=0	; Determine acceleration
			}
			out := this.IOControls.OA1.Get() + this.IncrementalDeflectionValues[direction] + (direction==1?-1:1)*acc
			this.accMode ? (tic:=A_TickCount, pdir:=direction) : acc:=0					; Update acceleration parameters
		} else {
			; Normal Mode - Set axis to deflection value on press, set to middle on release
			if (this.AxisButtonStates[1] == this.AxisButtonStates[2]){
				out := 50
			} else {
				if (this.AxisButtonStates[1]){
					out := this.DeflectionValues[1]
				} else {
					out := this.DeflectionValues[2]
				}
			}
		}
		this.IOControls.OA1.Set(out)
		GuiControl, , % this.hSlider, % out
	}
}
The Inerta setting guards the rate of acceleration, and Cap acceleration sets the maximum value of the acceleration. Reset timeout determines how often the input button has to be pressed before the acceleration resets, at 150 ms, acceleration basically just occurs when the input button is held down.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

05 Jan 2017, 05:44

Np, admittedly I threw it together on my coffee break, it has only been tested very briefly.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

05 Jan 2017, 15:18

@Helgef - I am not sure this is quite what myself and azerty had in mind, and am also not really sure what it is doing. Could you advise some good settings that really accentuate what it is doing?
I had more envisaged something that worked in normal (non-incremental) mode - basically emulating the way in which a game would interpret digital input for an analog axis.
ie, it is normally centered, but when you hold the High InputButton, it starts to build up to max deflection. If you release the key, it starts to decay back down to center.
The opposite for the Low InputButton - it moves towards min deflection, but still decays towards center.

@Azerty - can you confirm whether I am understanding your requirement correctly?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

05 Jan 2017, 17:51

evilC wrote: If you release the key, it starts to decay back down to center.
Ah, that it does not do. The point of this what to let you have a low incremental setting, for fine adjustments, but holding (or quickly tapping I guess) the input button, would accelerate the output, so you can get to the ends quickly if needed. I tested with settings like inertia 0 to 6 and cap 0 to 10, and a low deflection % like 1-5.
It wouldn't be hard to add a decay back to center I guess. I'd probably just set a timer. I might ponder it tomorrow if I get any coffee breaks. (I always do... :lol: )
keem85
Posts: 25
Joined: 03 Aug 2016, 03:14

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

06 Jan 2017, 06:18

Hi

I updated UCR to the latest (I don't remember my previous version, but I installed it almost a year ago..).. But with the latest UCR, it doesn't work with my installed vJoy.. I have X-axis activated on vJoy, and I choose it from the output dropdown menu.. Nothing happens when I move my pedals.. Input works just fine though... I can't save profile either.. Every time I start up UCR I get an error message that "vjoy is already in the dropdown" or something in the lines of that.. I get 8 of those error messages before UCR start..
How can I solve this? How can I make UCR find my vJoy plugin?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

06 Jan 2017, 07:14

@evilC
I added an option for decaying the output. It should work for both normal and incremental mode.
Rate determines how often (ms.) the deflection is decreased by amount Step. Delay is the time (ms.) before the first decrement is done, after that, decrements are done every Rate ms.
In code, there is a nonLinearFactor parameter that guards the behaviour of the non-linear decay. I'm not sure this is even desired.
Also changed the acceleration option to not use static variables :oops:
Initial testing shows no catastrophes.

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+0 w" iow " yp", Preview
		this.AddControl("OutputAxis", "OA1", 0, "xs+5 yp+15")
		Gui, Add, Slider, % "hwndhwnd x+0 yp", 50
		this.hSlider := hwnd
		
		; Acceleration settings
		Gui, Add, GroupBox, Center xm y80 w310 h45 section, Acceleration
		this.AddControl("CheckBox", "accMode", this.AccModeChanged.Bind(this), "xs+5 yp+20", "Enable")
		
		Gui, Add, Text, % "Center x+5 hwndinertiaText", % "Inertia:"
		this.inertiaText:=inertiaText
		this.AddControl("Edit", "inertiaEdit", this.inertiaChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 3)
		
		this.AddControl("CheckBox", "accCapCB", this.AccCapCBChanged.Bind(this), "x+5 yp+3 disabled", "Cap")
		this.AddControl("Edit", "accCapEdit", this.AccCapChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 5)
		
		Gui, Add, Text, % "Center x+5 yp+3 hwndresetText", % "Timeout:"
		this.resetText:=resetText
		this.AddControl("Edit", "resetEdit", this.resetChanged.Bind(this), "x+5 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+20 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:=""
		}
		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.resetEdit.hwnd
		GuiControl, % state ? "Enable" : "Disable", % this.resetText
	}
	
	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
		
		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
	}
	
	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)
	}
	
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

06 Jan 2017, 08:31

Hi again.
I made an option to allow movment of multiple axis, simultaneously. I guess that would be nice for incremental mode at least.
Image
The effect should be highlighted by the Preview sliders. Three sliders moving <==> three buttons held.
Code:

Code: Select all

class ButtonsToAxisAcc extends _UCR.Classes.Plugin {
	Type := "Remapper (Buttons To Axis) (Acceleration)"
	Description := "Remaps two InputButtons to one OutputAxis - Added acceleration option"
	
	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+0 w" iow " yp", Preview
		this.AddControl("OutputAxis", "OA1", 0, "xs+5 yp+15")
		Gui, Add, Slider, % "hwndhwnd x+0 yp", 50
		this.hSlider := hwnd
		
		; Acceleration settings
		Gui, Add, GroupBox, Center xm y80 w310 h45 section, Acceleration
		this.AddControl("CheckBox", "accMode", this.AccModeChanged.Bind(this), "xs+10 yp+20", "Enable")
		
		Gui, Add, Text, % "Center x+5 hwndinertiaText", % "Inertia:"
		this.inertiaText:=inertiaText
		this.AddControl("Edit", "inertiaEdit", this.inertiaChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 3)
		
		this.AddControl("CheckBox", "accCapCB", this.AccCapCBChanged.Bind(this), "x+5 yp+3 disabled", "Cap")
		this.AddControl("Edit", "accCapEdit", this.AccCapChanged.Bind(this), "x+5 yp-3 w30 center number disabled", 5)
		
		Gui, Add, Text, % "Center x+5 yp+3 hwndresetText", % "Timeout:"
		this.resetText:=resetText
		this.AddControl("Edit", "resetEdit", this.resetChanged.Bind(this), "x+5 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+20 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")
		
		; Friend plugin settings
		Gui, Add, GroupBox, Center xm y135 w655 h45 section, Friend plugin
		this.AddControl("CheckBox", "friendModeCB", this.FriendModeChanged.Bind(this), "xs+10 yp+20", "Enable")
		Gui, Add, Text, % "Center x+5 hwndfriendNamesText", % "Friend names (comma separated):"
		this.friendNamesText:=friendNamesText
		this.AddControl("Edit", "friendNamesEdit", 0, "x+5 yp-3 w200  disabled")
		Gui, Add, Button, % "x+5 hwndupdateFriendsButton", % "Update"
		this.updateFriendsButton:=updateFriendsButton
		gFunc := this.UpdateFriends.Bind(this)
		GuiControl +g, % this.updateFriendsButton, % gFunc
		
	}
	
	OnClose(){
		if (this.decayTimer){
			timerFunc:=this.decayTimer
			try
				SetTimer, % timerFunc, delete
			this.decayTimer:=""
		}
		this.friends:=""
		GuiControl, -g, % this.updateFriendsButton
		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
	}
	
	; Friend settings
	FriendModeChanged(state){
		this.friendMode:=state
		GuiControl, % state ? "Enable" : "Disable", % this.GuiControls.friendNamesEdit.hwnd
		GuiControl, % state ? "Enable" : "Disable", % this.friendNamesText
		GuiControl, % state ? "Enable" : "Disable", % this.updateFriendsButton
		state ? this.UpdateFriends() : this.friends:=""
	}
	
	UpdateFriends(){
		names:=this.GuiControls.friendNamesEdit.Get()
		this.friends:=[]
		for k, plugin in this.ParentProfile.Plugins
			if (plugin!=this && InStr(names,plugin.name))
				this.friends.Push(plugin)
		!this.friends.length() ? this.friends:="" : ""
	}
	
	; 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.resetEdit.hwnd
		GuiControl, % state ? "Enable" : "Disable", % this.resetText
	}
	
	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, canCallFriend:=true){
		;OutputDebug % "UCR| Axis: " axis ", Direction: " direction ", value: " value
		
		if (!this.IncrementalMode && this.AxisButtonStates[direction] = value)
			return	; filter repeats if not in Incremental Mode
		
		this.AxisButtonStates[direction] := value
		
		if (this.IncrementalMode){
			; Incremental Mode - alter current axis by deflection value on press
			if (!value){
				this.decayMode ? this.setDecayTimer() : ""
				this.state:=0
				return	; Do nothing on release
			}
			this.state:=[direction, value]
			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()
					this.state:=0
					return
				}
				else {
					out:=50
				}
			} else {
				this.state:=[direction, value]
				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
		this.friendMode && canCallFriend ? this.CallFriends() : ""
	}
	
	CallFriends(){
		for k, friend in this.friends
			friend.state ? friend.ButtonInput(friend.state[1],friend.state[2], false) : ""
	}
	
	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)
	}
	
}
Basically, the friendship means that friends who interupts you will call you with your latest (ButtonInput(direction, value)) settings.
All friendships need to be mutual and you need to press the update button for all plugins every time you change the friend list or start UCR, slightly awkward I guess.
Just in case someone wants it, and also beacuse I like making those gifs ;)
keem85
Posts: 25
Joined: 03 Aug 2016, 03:14

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

06 Jan 2017, 13:04

Do you guys know anything about the problem I'm facing? I have the correct output of error here now: "Error. A SubMenu with the name vJoy already exists in this menu". It's popping up 8 times before I am allowed to enter.. Also there is no output to my vJoy axis.... vJoy is working fine when I test it with the vJoy-feeder.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: Universal Control Remapper (UCR) - v0.1.9 26th Dec 2016

06 Jan 2017, 15:00

@keem85 Yeah, this is a known error message, but I am not 100% sure what is causing it in this instance.
It was happening for everyone with the last release, but I thought I fixed it in the current version.
What vJoy version are you using? You should be using the latest version as there have been a load of features added to vJoy over the last year which UCR makes use of.
If you could make a note of your vJoy version before upgrading, that would be great.
Even if you do not have the correct version, it should gracefully fail, not spout some cryptic error message - so if I can reproduce the issue on my PC by installing an old version of vJoy, I should be able to sort that out.
I seem to remember that some previous causes of this were related to broken vJoy installs, and I think that it became more prolific with the recent broken vJoy release which was missing the vGenInterface.dll files in the x86/x64 folders in the vJoy install folder - so upon installing the new version of vJoy, I would advise double-checking that those files are present.

Return to “Gaming Scripts (v1)”

Who is online

Users browsing this forum: No registered users and 41 guests