LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Having the D-pad give the same output as the circle pad

Root / Programming Questions / [.]

SamCreated:
Hi. Title. For convenience, let's say the input variables are called IX and IY.
STICK OUT IX, IY
I'm interested in seeing the cleanest, most efficient code we could use to have the D-pad give the same outputs as the stick. Bonus points if it's a function. Maybe something like this:
'B is for the BUTTON() input
DEF DPAD B OUT IX, IY
 IX=0:IY=0
 IF (B AND 1)!=0 THEN IX=0:IY=-0.875
 IF (B AND 2)!=0 THEN IX=0:IY=0.875
 IF (B AND 4)!=0 THEN IX=-0.875:IY=0
 IF (B AND 8)!=0 THEN IX=0.875:IY=0
 'More IF statements for all 4 diagonals...
END
I know it isn't necessary to have the function ask for B (we could just do B=BUTTON() in the function itself) but most programs also use other buttons, so it seems better to only do B=BUTTON() once at the beginning of the program's main loop. So yeah, is this the most efficient way? And what IX and IY values should we use for the diagonal inputs if we want them to feel the same as the stick?

I wrote an input library that contained this code last year. (stick input was normalized to 1.0, and where UDLR are boolean only)
DEF BTN_TO_ANALOG U%,D%,L%,R% OUT X,Y
  UNITVECTOR R% - L%, U% - D% OUT X, Y
END

DEF UNITVECTOR X, Y OUT UX, UY
  VAR ANGLE# = ATAN(Y, X)
  UX = COS(ANGLE#)
  UY = SIN(ANGLE#)
END
For this purpose, optimized for lines:
DEF DPAD B OUT IX, IY IX = 0.875 * -SIN(ATAN(!(B AND 8) - !(B AND 4), !(B AND 2) - !(B AND 1))) IY = 0.875 * SIN(ATAN(!(B AND 2) - !(B AND 1), !(B AND 8) - !(B AND 4))) END

DEF DPAD B OUT X,Y
 X=0.875*(!!(B AND #RIGHT)-!!(B AND #LEFT))
 Y=0.875*(!!(B AND #DOWN)-!!(B AND #UP))
 IF X && Y THEN
  X=X*SQR(1/2)
  Y=Y*SQR(1/2)
 ENDIF
END
The X/Y values for diagonals are 0.875 * SQR(2)/2