Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
And when I press two buttons at the same time one end up getting stuck
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Set it up with one plugin per axis, then check joy.cpl as mentioned.
Is the joystick *really* getting stuck in the corners, or does the game just think it does?
Is the joystick *really* getting stuck in the corners, or does the game just think it does?
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
That, Sir, is exactly what I need.evilC wrote:@Oliver So you want a remapper that preserves your detente position?
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Yes they be getting stuck in the corners or sometimes on the left or down...and that's where I see that they get stuck at in.joy.cpl
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Oliver wrote:That, Sir, is exactly what I need.evilC wrote:@Oliver So you want a remapper that preserves your detente position?
It would be totally trivial to make a plugin with custom logic, we just need to work out the formula that dictates what the output should be, given an input value.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
So what formula are you looking for, the one that would plot the graph I posted? Because that one would need two inputs (X,Y). It would result in a line drawn from (0,0) to (X,Y) and from (X,Y) to (100,100).
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Well it does not need to be a mathematical formula, we just need to work out what parameters are required and what calculations to do with them.
As far as I can tell, we need 3 values:
1) The raw input value
2) The point of the physical detent
3) The point of the virtual detent
Although given these 3 values, I am not quite sure yet how you would end up with the correct answer.
As far as I can tell, we need 3 values:
1) The raw input value
2) The point of the physical detent
3) The point of the virtual detent
Although given these 3 values, I am not quite sure yet how you would end up with the correct answer.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Think I have it...
Given your example where the input detent is at 80%, and the output detent is at 60%...
Given your example where the input detent is at 80%, and the output detent is at 60%...
Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus
#SingleInstance force
InDetent := 80
OutDetent := 60
LowFactor := OutDetent / InDetent
HighFactor := (100  OutDetent) / (100  InDetent)
Gui, Add, Edit, gEditChanged vValue
Gui, Show, x0 y0
EditChanged:
Gui, Submit, NoHide
if (value < InDetent){
output := LowFactor * value
} else {
output := OutDetent + ((value  Indetent) * HighFactor )
}
ToolTip % output
return
GuiClose:
ExitApp
Last edited by evilC on 11 Jan 2018, 14:17, edited 1 time in total.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Aight, where do I put that stuff to test it?
I take it the 'curves' are linear up to the detent point as well as from the detent point to (100%,100%)?
I take it the 'curves' are linear up to the detent point as well as from the detent point to (100%,100%)?
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
I didn't follow the disscusion, but this graph clearly is,
Code: [Select all] [Download] GeSHi © Codebox Plus
f(x){
static breakPoint := ?
if (x < breakPoint )
return x
return 2*x
}
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Ehm... Sorry, but I don't think so.
For starters, your formula says if X < breakpoint, then y = x. So let's take my graph, breakpoint is at X = 80 and Y = 60. With your formula, X = 80 would yield Y = 80...
If I read your formula correctly it basically says: before the breakpoint Y = X, after the breakpoint Y = x2. While my example graph may look like that, the formula doesn't support the flexibility of moving the breakpoint to an Xcoord and Ycoord of my choice.
For starters, your formula says if X < breakpoint, then y = x. So let's take my graph, breakpoint is at X = 80 and Y = 60. With your formula, X = 80 would yield Y = 80...
If I read your formula correctly it basically says: before the breakpoint Y = X, after the breakpoint Y = x2. While my example graph may look like that, the formula doesn't support the flexibility of moving the breakpoint to an Xcoord and Ycoord of my choice.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Yes, clearly my eyes were crossed. You should return x*8/7 before the breakpoint as it seems.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Oliver wrote:Aight, where do I put that stuff to test it?
That is a standalone script, not part of UCR. It was just meant to allow us to test proposed logic.
It's just a form with an editbox  you type in the input value and it displays the output value as a tooltip
Just tryin' to work out the calculations that need to be done and the best way to implement them in AHK code. Once we know what code we need, I can quickly whip up a plugin.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
That's fair. In any case, isn't it easier to just have the user defined X breakpoint and Y breakpoint as percentage of Xmax and Ymax? Formula for a linear line before the breakpoint as well as after the breakpoint would be:
This is basically the formula for a linear line: Slope Coefficient = ( deltaY / deltaX ) but it generates a slope coefficient for the linear line before the breakpoint and one for the linear line after the breakpoint.
Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus
Xpb = <user defined percentage between 0% and 100%>
Ybp = <user defined percentage between 0% and 100%>
Xmax = <max. raw value of PhysicalJoy1Axis1>
Ymax = <max. raw value of VirtualJoy1Axis1>
if X <= ( Xpb * Xmax )
then
Y = ( Ybp * Ymax ) / ( Xbp * Xmax ) * X
else
Y = ( Ymax  ( Ybp * Ymax ) ) / ( Xmax  ( Xbp * Xmax ) ) * X
This is basically the formula for a linear line: Slope Coefficient = ( deltaY / deltaX ) but it generates a slope coefficient for the linear line before the breakpoint and one for the linear line after the breakpoint.

 Posts: 1
 Joined: 11 Jan 2018, 16:48
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Thanks evilC, for the work on UJR and now UCR. Fantastic utilities.
There was one feature in UJR that I have been unable to replicate in UCR: the "Rests L"/"Rests H" selections in the special operations dropdown for mapped axis. Is there another way to apply a deadzone to the ends of a range in UCR?
An additional feature that would be welcome would be multiple deadzone adjustments for a single axis. Perhaps this could be implimented with a plugin dedicated to applying deadzones to previously mapped axes, and include deadzone setting for range extents, and also separate deadzone settings for either side of center.
In the meantime, I will continue to use UJR, which works great, but lacks the axis range to button mapping.
There was one feature in UJR that I have been unable to replicate in UCR: the "Rests L"/"Rests H" selections in the special operations dropdown for mapped axis. Is there another way to apply a deadzone to the ends of a range in UCR?
An additional feature that would be welcome would be multiple deadzone adjustments for a single axis. Perhaps this could be implimented with a plugin dedicated to applying deadzones to previously mapped axes, and include deadzone setting for range extents, and also separate deadzone settings for either side of center.
In the meantime, I will continue to use UJR, which works great, but lacks the axis range to button mapping.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
In UCR, all axes are get/set in the range 0..100, so it makes life simpler.
So, to make the plugin, all you do is this:
Copy Plugins\Core\AxisToAxis.ahk to the Plugins\User folder
Rename it to AxisToAxisDetent.ahk
Edit it in a text editor, change the first couple of lines, wherever it says AxisToAxis, replace with AxisToAxisDetent (The class name MUST match the file name, the descriptions, not so important)
Then for now I just added a little extra code in two places  the end of Init(), and the end of MyInputChangedState().
In both instances, where I added extra stuff I put some comments like
For now you can set the breakpoint values in the code, but if all works well I will rig up guicontrols to do it. We can probably lose the sensitivity / deadzone as well, that makes no real sense in this scenario
So, to make the plugin, all you do is this:
Copy Plugins\Core\AxisToAxis.ahk to the Plugins\User folder
Rename it to AxisToAxisDetent.ahk
Edit it in a text editor, change the first couple of lines, wherever it says AxisToAxis, replace with AxisToAxisDetent (The class name MUST match the file name, the descriptions, not so important)
Then for now I just added a little extra code in two places  the end of Init(), and the end of MyInputChangedState().
In both instances, where I added extra stuff I put some comments like
; Detent Mod Start / End
For now you can set the breakpoint values in the code, but if all works well I will rig up guicontrols to do it. We can probably lose the sensitivity / deadzone as well, that makes no real sense in this scenario
Code: [Select all] [Expand] [Download] (AxisToAxisDetent.ahk)GeSHi © Codebox Plus
class AxisToAxisDetent extends _UCR.Classes.Plugin {
Type := "Remapper (Axis To Axis with Detent)"
Description := "Maps an axis input to a virtual axis output (With Detent)"
vAxis := 0
vDevice := 0
; Set up the GUI to allow the user to select input and output axes
Init(){
Gui, Add, Text, % "xm w125 Center", Input Axis
Gui, Add, Text, % "x+5 yp w100 Center", Input Preview
Gui, Add, Text, % "x+5 yp w40 Center", Invert
Gui, Add, Text, % "x+5 yp w40 Center", Deadzone
Gui, Add, Text, % "x+5 yp w40 Center", Sensitivity
Gui, Add, Text, % "x+5 yp w30 Center", Linear
Gui, Add, Text, % "x+10 yp w125 Center", Output Virtual Axis
Gui, Add, Text, % "x+5 yp w100 Center", Output Preview
;this.AddInputAxis("InputAxis", 0, this.MyInputChangedState.Bind(this), "xm w125")
this.AddControl("InputAxis", "IA1", 0, this.MyInputChangedState.Bind(this), "xm w125")
this.AddControl("AxisPreview", "", 0, this.IOControls.IA1, "x+5 yp w100", 50)
;this.AddControl("Invert", 0, "CheckBox", "x+20 yp+3 w30")
this.AddControl("CheckBox", "Invert", 0, "x+20 yp+3 w30")
;this.AddControl("Deadzone", 0, "Edit", "x+10 yp3 w30", "0")
this.AddControl("Edit", "Deadzone", 0, "x+10 yp3 w30", "0")
Gui, Add, Text, % "x+0 yp+3", `%
;this.AddControl("Sensitivity", 0, "Edit", "x+10 yp3 w30", "100")
this.AddControl("Edit", "Sensitivity", 0, "x+10 yp3 w30", "100")
Gui, Add, Text, % "x+0 yp+3", `%
;this.AddControl("Linear", 0, "Checkbox", "x+18 yp w30")
this.AddControl("Checkbox", "Linear", 0, "x+18 yp w30")
;this.AddOutputAxis("OutputAxis", this.MyOutputChangedValue.Bind(this), "x+5 yp3 w125")
this.AddControl("OutputAxis", "OA1", this.MyOutputChangedValue.Bind(this), "x+5 yp3 w125")
this.AddControl("AxisPreview", "", 0, this.IOControls.OA1, "x+5 yp w100", 50)
; Detent Mod Start
this.InDetent := 80 ; Change this value to tweak xbp
this.OutDetent := 60 ; Change this value to tweak ybp
this.LowFactor := this.OutDetent / this.InDetent
this.HighFactor := (100  this.OutDetent) / (100  this.InDetent)
; Detent Mod End
}
; The user changed options  store stick and axis selected for fast retreival
MyOutputChangedValue(value){
this.vAxis := value.Binding[1]
this.vDevice := value.DeviceID
this.OutputBound := value.IsBound()
}
; The user moved the selected input axis. Manipulate the output axis accordingly
MyInputChangedState(value){
value := UCR.Libraries.StickOps.AHKToInternal(value)
if (this.OutputBound){
if (this.GuiControls.Deadzone.Get()){
value := UCR.Libraries.StickOps.Deadzone(value, this.GuiControls.Deadzone.Get())
}
if (this.GuiControls.Sensitivity.Get()){
if (this.GuiControls.Linear.Get())
value *= (this.GuiControls.Sensitivity.Get() / 100)
else
value := UCR.Libraries.StickOps.Sensitivity(value, this.GuiControls.Sensitivity.Get())
}
if (this.GuiControls.Invert.Get()){
value := UCR.Libraries.StickOps.Invert(value)
}
value := UCR.Libraries.StickOps.InternalToAHK(value)
; Detent Mod Start
if (value <= this.InDetent){
value := this.LowFactor * value
} else {
value := this.OutDetent + ((value  this.Indetent) * this.HighFactor )
}
; Detent mod End
; Set the output (0..100)
this.IOControls.OA1.Set(value)
}
}
}
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Hello again.
For an arbitrary amount of arbitrary breakpoints,
Input for
The top image is
Image credis:
Cheers.
the formula doesn't support the flexibility of moving the breakpoint to an Xcoord and Ycoord of my choice.
For an arbitrary amount of arbitrary breakpoints,
Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus
; Example
segs := segmentsFromPoints([0,0], [80,70], [100,110])
segmentsFromPoints(pts*){
pts := pts.clone()
p0 := pts.removeat(1)
segs := []
for i, p1 in pts
segs.push( {k : (p1.2p0.2) / (p1.1p0.1) , m : ( p1.1*p0.2  p0.1*p1.2 ) / (p1.1p0.1), end : p1.1 } ), p0 := p1
return segs
}
f(x, segs){
for i, seg in segs
if (x < seg.end)
return x*seg.k+seg.m
}
Input for
segmentsFromPoints(startPoint, breakPoint1,...,breakPointN, endPoint)
. Points are defined as [x, y]
. You call segmentsFromPoints
once per setup. Then you get y := f(x, segs)
for every x
.The top image is
segs := segmentsFromPoints([0,20],[30,80], [50,40], [60,70], [100,100])
. The bottom image is segs := segmentsFromPoints([0,0], [80,70], [100,110])
.Image credis:
SVGraph.ahk
.Cheers.
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
@ evilC
I'm assuming LowFactor is the slope factor for when X <= Xbreakpoint and HighFactor is the slope factor for when X > Xbreakpoint.
The formula seems to work for Xbreakpoint = Ybreakpoint which makes sense as that would result in Ybreakpoint / Xbreakpoint = 1. This yields a linear translation.
However, for different values of Xbp and Ybp something is not quite right. I'm trying to figure out what you're attempting to do when the HighFactor should be used but I'm currently not following that and cannot relate it to my formula. I'll try again tomorrow with a fresh brain (midnight here).
PS  Your response to user input/requests is awesome!
I'm assuming LowFactor is the slope factor for when X <= Xbreakpoint and HighFactor is the slope factor for when X > Xbreakpoint.
The formula seems to work for Xbreakpoint = Ybreakpoint which makes sense as that would result in Ybreakpoint / Xbreakpoint = 1. This yields a linear translation.
However, for different values of Xbp and Ybp something is not quite right. I'm trying to figure out what you're attempting to do when the HighFactor should be used but I'm currently not following that and cannot relate it to my formula. I'll try again tomorrow with a fresh brain (midnight here).
PS  Your response to user input/requests is awesome!
Re: Universal Control Remapper (UCR)  v0.1.19 26th Dec 2017
Oh fuck me!
It seems for both my physical throttle axes as well as the vJoy sliders, sliders down/idle = 100, sliders maxed = 0. So the values for InDetent and OutDetent have to be '100  desired percentage' instead of 'desired percentage'.
It seems for both my physical throttle axes as well as the vJoy sliders, sliders down/idle = 100, sliders maxed = 0. So the values for InDetent and OutDetent have to be '100  desired percentage' instead of 'desired percentage'.
Who is online
Users browsing this forum: No registered users and 4 guests