Previous Thread
Next Thread
Print Thread
Rate This Thread
Hop To
#4282555 - 07/28/16 05:08 AM Square the circle - make Warthog reach the corners *****  
Joined: May 2006
Posts: 123
DarKcyde Offline
Member
DarKcyde  Offline
Member

Joined: May 2006
Posts: 123
Have you ever noticed that the Warthog joystick can't quite reach the corners? Depending on mods done, this can get worse (I think my teflon gasket replacement made it worse). It always bothered me, how can such a powerful stick have such a glaring flaw? When I want to barrel roll, I want full deflection on both axes! I knew the solution was out there. Some googling finally turned up some smart math people with the right equations, and got to coding.

The math bits came from this guy: Simple Stretching: Mapping a circular disc to a square
Analytical Methods for Squaring the Disc

This function is like a reverse deadzone... it extends the rounded off corners of the joystick input out to the very end of the DX axis. The input is normalized so there is no change in sensitivity or curve, beyond what is required to stretch input out to the corners.

Like this (except our circle isn't so severe, this one is from an xbox controller)


Code:
include "target.tmh"

int main()
{
    if(Init(&EventHandle)) return 1;

	MapAxis(&Joystick, JOYX, DX_X_AXIS, AXIS_NORMAL, MAP_ABSOLUTE);
		SetSCurve(&Joystick, JOYX, 0, 0, 0, 0, 0);
	MapAxis(&Joystick, JOYY, DX_Y_AXIS, AXIS_NORMAL, MAP_ABSOLUTE);
		SetSCurve(&Joystick, JOYY, 0, 0, 0, 0, 0);
}

int sign(float x)  //sgn func is int only, need one for float
{
if (x > 0) return 1;
if (x < 0) return -1;
return 0;
}

//SquareTheCircle by DarKcyde
//squircular.blogspot.ca/2015/09/elliptical-arc-mapping.html
//arxiv.org/ftp/arxiv/papers/1509/1509.06344.pdf
//Simple Stretching formula from the paper

int SquareTheCircle(alias dev, int ax, int x, int y)
{
	float newx, newy;
	float u = dev[x] / 32767.0;
	float v = dev[y] / 32767.0;
	
	float u2 = u * u;
	float v2 = v * v;
	float r = sqrt(u2 + v2);
	if (u2 >= v2) {
		newx = sign(u) * r;
		if (u) {  //catch divide by zero
			newy = sign(u) * v/u * r;
		}
		else newy = v;
	}
	else if(u2 < v2) {
		if (v) {  //catch divide by zero
			newx = sign(v) * u/v * r;
		}
		else newx = u;
		newy = sign(v) * r;
	}
	
	GetAxisData(&dev, ax);
	if (ax == JOYX) {
		axdata.val = clip(newx * 32767.0, -AMAX, AMAX);
	}
	if (ax == JOYY) {
		axdata.val = clip(newy * 32767.0, -AMAX, AMAX);
	}
	if(!!axdata.dxmap & !axdata.locked & !axdata.relative) DXAxis(axdata.dxmap, axdata.val);
}


int EventHandle(int type, alias o, int x)
{
	if (&o == &Joystick & (x == JOYX | x == JOYY)) {
		SquareTheCircle(&o, x, JOYX, JOYY);
	}
    else DefaultMapping(&o, x);
}

Last edited by DarKcyde; 07/28/16 05:53 AM.
Inline advert (2nd and 3rd post)

#4282784 - 07/28/16 06:48 PM Re: Square the circle - make Warthog reach the corners [Re: DarKcyde]  
Joined: Feb 2010
Posts: 158
skunk160 Offline
Member
skunk160  Offline
Member

Joined: Feb 2010
Posts: 158
London UK/Colorado
Genius.

so save this code as target.tmh? how best to use this?


//FOXTWO Multi-Role ​Combat ​Pit Build http://forums.eagle.ru/showthread.php?t=134745
#4283043 - 07/29/16 06:19 PM Re: Square the circle - make Warthog reach the corners [Re: DarKcyde]  
Joined: May 2006
Posts: 123
DarKcyde Offline
Member
DarKcyde  Offline
Member

Joined: May 2006
Posts: 123
No, Target.tmh is all the crazy stuff that actually makes Target do what it does. You just integrate this into your <whatever game>.tmc. Easiest way is just grab everything below the main() section, and paste it over your int EventHandle().

You could save the two functions sign() and SquareTheCircle() into their own .tmh file, include it from the top of your .tmc, and modify the EventHandle as shown.

#4283773 - 08/01/16 02:20 PM Re: Square the circle - make Warthog reach the corners [Re: DarKcyde]  
Joined: Mar 2011
Posts: 14
Thermal Offline
Junior Member
Thermal  Offline
Junior Member

Joined: Mar 2011
Posts: 14
Firstly - this is totally brilliant. My reaction was "WOAH" *think* *think* "...COOOOL!"

Then I tested the theory.

I firstly fired up the Thrustmaster analyzer, and tested my corners. I dont think I'd used my warthog since the last reboot.

Tried top left corner - best I could do was 95,95. I could get to 0,y and x,0 - just not at the same time - so far, so good.

Then I tried to get other corners - and got the same behavior - I was initially about 64500,64500 in the bottom right corner..

Then I applied just a little more force to see what I could really get the corners too. And I could get to 0,0, and 65535,65535. And now its "easy". There seems to be no edge deadzone, I can get to the full corners, and it seems to "work" like a square bounding box.

So my guess is that there is some self-calibrating going on in the first instance, and I wonder if there is some fancy maths going on in the firmware too.

So - at least on my stick - it seems to be maybe not really an issue.

I really admire the fact you came up with the idea and then coded it. When I have some more time I'm certainly going to dig into your code to examine the method of what your doing. It will certainly be useful to me and others somewhere smile

#4284510 - 08/03/16 10:51 PM Re: Square the circle - make Warthog reach the corners [Re: DarKcyde]  
Joined: May 2006
Posts: 123
DarKcyde Offline
Member
DarKcyde  Offline
Member

Joined: May 2006
Posts: 123
Thermal, if you stick is using the stock rubber O-ring, you likely don't have as much deadzone as I do. I got one of the teflon replacements. It's about twice as thick as the o-ring, and doesn't compress at all. Also, the gimbal is plastic, so it could be parts of that just flexing/compressing. I can force the stick into the corner too, but it's an amount of force I'm uncomfortable with. If I kept doing it, the gimbal would shatter eventually.

The code isn't perfect. It expects an input circle with a radius of AMAX. I don't really have a circle, more of a square with rounded corners. This causes it to overshoot a bit towards the corners, but I don't notice while playing.

Thanks for the kind words smile


Moderated by  RacerGT 

Quick Search
Recent Articles
Support SimHQ

If you shop on Amazon use this Amazon link to support SimHQ
.
Social


Recent Topics
Carnival Cruise Ship Fire....... Again
by F4UDash4. 03/26/24 05:58 PM
Baltimore Bridge Collapse
by F4UDash4. 03/26/24 05:51 PM
The Oldest WWII Veterans
by F4UDash4. 03/24/24 09:21 PM
They got fired after this.
by Wigean. 03/20/24 08:19 PM
Grown ups joke time
by NoFlyBoy. 03/18/24 10:34 PM
Anyone Heard from Nimits?
by F4UDash4. 03/18/24 10:01 PM
RIP Gemini/Apollo astronaut Tom Stafford
by semmern. 03/18/24 02:14 PM
10 years after 3/8/2014
by NoFlyBoy. 03/17/24 10:25 AM
Copyright 1997-2016, SimHQ Inc. All Rights Reserved.

Powered by UBB.threads™ PHP Forum Software 7.6.0