Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Joystick: cannot reach corners #429

Closed
audetto opened this issue Jun 11, 2017 · 15 comments
Closed

Joystick: cannot reach corners #429

audetto opened this issue Jun 11, 2017 · 15 comments

Comments

@audetto
Copy link
Contributor

audetto commented Jun 11, 2017

Hi,

I'm using AppleWin 1.26.2.4 via Wine and I've realised I struggle to move the joystick in the corners, especially TopRight and Top Left.

For instance, this means I cant run when I play Karateka.

I've tried to use COLOR DEMOSOFT from the Apple DOS 3.3 disk and indeed I cannot cover the whole screen.

I am using a XBOX 360 controller, and it looks like the control is a circle and not a square like the Apple 2 Joystick.

Or maybe it is an artifact introduced by Wine?

color demosoft

@tomcw
Copy link
Contributor

tomcw commented Jun 11, 2017

Using a controller with analogue thumbsticks (in my case a PS4 Dualshock 4) I get the same result as you. I'm running natively on Win7-64.

I've tested with 1.25.0.4 and the latest from git master (ie. after Nick's latest changes in this area). Both behave the same - ie. as reported in this issue.

A link to COLOR DEMOSOFT is here.

A simpler repro is from AppleSoft run this simple code:

10 ?PDL(0),PDL(1): GOTO 10

...you can't get both values to be simultaneously 0.

NB. Using a mouse as a joystick works fine - full coverage in all corners & everywhere else on the screen. Also cursor keys and a USB digital joypad work "fine" (albeit the granularity is only left/centre/right, ie: 0/128/255).

@audetto
Copy link
Contributor Author

audetto commented Jun 11, 2017

I was thinking that one can remap the circle to the square.

If x and y are in the unit circle centred at 0,0

C = min(x^2 / y^2, y^2 / x^2)
D = Sqrt(1 + C)

D is basically the length of the line from 0,0 passing by x,y till the edge of the square.

xD and yD will cover the unit square.
I have not tried it and cannot say how much distortion it introduces.

@sicklittlemonkey
Copy link
Contributor

sicklittlemonkey commented Jun 12, 2017 via email

@audetto
Copy link
Contributor Author

audetto commented Jun 12, 2017

The first one has the same formula I posted above, just with too many ifs.
They do an interesting remapping (pow) at the end to re-establish some round-ness in the middle where there would be no need to change anything.

The 2nd one is interesting where it mentions that values on the edges are not reliable and should be clamped down, plus all the dead zones for most common gestures.

This smells of a scriptable lua function to control the emulator behaviour .... :-)

While playing with AppleWin I was trying to get familiar with the way PDL(.) works and found out this interesting behaviour.

If the joystick is stable in a given position, there is no way for PDL(.) to ever return 232.

PDL(.) will normally return the value of nPdlPos if this is in the range 0-231

nPdlPos = 231 -> PDL() = 231
nPdlPos = 232 -> PDL() = 233
and so on till
nPdlPos = 254 -> PDL() = 255
nPdlPos = 255 -> PDL() = 255

This has to do with the fact that the first Read happens 10 cycles after the reset (and not 11), and the way PDL_CNTR_INTERVAL is computed (11.04 rather than 11).

And I guess the line nPdlPos = 280; only matters if one is not using PREAD but has written a different paddle position check routine.

No big deal, but happy to have understood how it works.

Andrea

@sicklittlemonkey
Copy link
Contributor

sicklittlemonkey commented Jun 12, 2017 via email

@audetto
Copy link
Contributor Author

audetto commented Jun 14, 2017

I have tried the transformation and I am now able to run in Karateka using an Xbox gamepad.

I don't know if this milestone is important enough to deserve a configuration option, but in a few days with a bit of time I will post the code so other people can share opinion.

@audetto
Copy link
Contributor Author

audetto commented Jun 18, 2017

There is a branch with 2 proposals.

https://github.com/audetto/AppleWin/tree/joystick

Either 1) remap the circle to the square or basically 2) restrict the valid movement to the square inside the unit circle.

With either I can reach the 4 corners in Color Demosoft and run in karateka.

@sicklittlemonkey
Copy link
Contributor

Great, thanks. Here's a hires test program.

10 HGR : HCOLOR= 3: HOME
20 X = PDL (0):PX = X + 12
30 Y = PDL (1):PY = Y * (159 / 255)
40 IF PEEK (49249) > 127 THEN HPLOT TO PX,PY
50 HPLOT PX,PY
60 VTAB 22: PRINT "X="X" "
70 PRINT "Y="Y" "
80 IF PEEK (49250) > 127 GOTO 10
90 IF PEEK (49168) > 127 THEN TEXT : END
99 GOTO 20

I'm not feeling much difference between the two methods ...

Cheers,
Nick.

@audetto
Copy link
Contributor Author

audetto commented Jun 20, 2017

neither do I. so the easier the better probably.

with the sqrt(2) method, if your thumb is super sensitive, you should see that horizontally or vertically you reach the end sooner and then nothing else happens for the last bit.

while the more complex method, the diagonal movement is faster that the axis aligned moves.

but with the size of the gamepads, it is probably so hard to tell apart.

@tomcw
Copy link
Contributor

tomcw commented Jun 18, 2023

I've tested PR #1242 with a digital-only controller (ie. D-pad, no analog stick) and a Sony DualShock 4 (which has 2 analog sticks), and both work fine.

For info, here are the JOYCAPS output from joyGetDevCaps():

"PCline", digital-only controller:
joyPCLine.txt

Sony DualShock 4:
joyDS4.txt

NB. there's no info in this struct to say if the controller has analog sticks or not.

tomcw added a commit that referenced this issue Jun 19, 2023
@tomcw tomcw added this to the 1.30.15 milestone Jun 19, 2023
@tomcw
Copy link
Contributor

tomcw commented Jun 19, 2023

I've merged the improvement (Andrea's code - ie. the first one above) into the mainline. Closing.

@tomcw tomcw closed this as completed Jun 19, 2023
@sicklittlemonkey
Copy link
Contributor

Wow, a blast from the past. Great to get it merged.

My only suggestion is a stylistic one: I like to see patterns in code, and names are important, so I would have preferred:
const double x[2] = { ((double)xpos[joyNum]) / (0.5 * 255) - 1.0, ((double)ypos[joyNum]) / (0.5 * 255) - 1.0};
->
const double x = ((double)xpos[joyNum]) / (0.5 * 255) - 1.0;
const double y = ((double)ypos[joyNum]) / (0.5 * 255) - 1.0;
etc.

But again, nice to see this problem fixed!

@tomcw
Copy link
Contributor

tomcw commented Jun 20, 2023

Hi Nick - I should've added you to the PR review.
Anyway, I agree with your point, so I've improved the code as per your suggestion (f8d238f)

@sicklittlemonkey
Copy link
Contributor

Oh, very nice. ; - )

@tomcw
Copy link
Contributor

tomcw commented Jul 29, 2023

@audetto - Fixed in AppleWin 1.30.15.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants