|
VbaGX Input Code Fix January 24, 2012 12:39PM | Registered: 14 years ago Posts: 4 |
u32 StandardMovement(unsigned short chan)
{
u32 J = 0;
s8 pad_x = userInput[chan].pad.stickX;
s8 pad_y = userInput[chan].pad.stickY;
#ifdef HW_RVL
s8 wm_ax = userInput[0].WPAD_StickX(0);
s8 wm_ay = userInput[0].WPAD_StickY(0);
#endif
/***
Gamecube Joystick input, same as normal
***/
// Is XY inside the "zone"?
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
{
if (pad_y == 0)
{
if(pad_x > 0)
{
J |= VBA_RIGHT;
}
else if(pad_x < 0)
{
J |= VBA_LEFT;
}
}
if (pad_x == 0)
{
if(pad_y > 0)
{
J |= VBA_UP;
}
else if(pad_y < 0)
{
J |= VBA_DOWN;
}
}
if ((pad_x|pad_y) != 0)
{
if ((fabs((double)(pad_y) / (double)(pad_x))) < 2.41421356237)
{
if (pad_x >= 0)
J |= VBA_RIGHT;
else
J |= VBA_LEFT;
}
if ((fabs((double)(pad_x) / (double)(pad_y))) < 2.41421356237)
{
if (pad_y >= 0)
J |= VBA_UP;
else
J |= VBA_DOWN;
}
}
}
#ifdef HW_RVL
/***
Wii Joystick (classic, nunchuk) input
***/
// OLD CODE: Doesn't work properly..
//// Is XY inside the "zone"?
//if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
//{
// /*** we don't want division by zero ***/
// if (wm_ay == 0)
// {
// if(wm_ax > 0)
// {
// J |= VBA_RIGHT;
// printf("RIGHT");
// return J;
// }
// else if(pad_x < 0)
// {
// J |= VBA_LEFT;
// printf("LEFT");
// return J;
// }
// }
// if (wm_ax == 0)
// {
// if(wm_ay > 0)
// {
// J |= VBA_UP;
// printf("UP");
// return J;
// }
// else if(pad_y < 0)
// {
// J |= VBA_DOWN;
// printf("DOWN");
// return J;
// }
// }
////
// if (wm_ax != 0 && wm_ay != 0)
// {
// if ((fabs((double)(wm_ay) / (double)(wm_ax))) < 2.41421356237)
// {
// if (wm_ax >= 0)
// {
// J |= VBA_RIGHT;
// printf("RIGHT");
// return J;
// }
// else
// {
// J |= VBA_LEFT;
// printf("LEFT");
// return J;
// }
// }
// if ((fabs((double)(wm_ax) / (double)(wm_ay))) < 2.41421356237)
// {
// if (wm_ay >= 0)
// {
// J |= VBA_UP;
// return J;
// }
// else
// {
// J |= VBA_DOWN;
// return J;
// }
// }
// }
//}
/// OLD CODE: Doesn't work properly.
// Input Detected (NEW CODE)
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
// inside the 'valid direction' block.
double angle = atan2(wm_ay, wm_ax);
const double THRES = 1.0 / sqrt(2.0);
if ( cos(angle) > THRES )
J |= VBA_RIGHT;
else if ( cos(angle) < -THRES )
J |= VBA_LEFT;
if ( sin(angle) > THRES )
J |= VBA_UP;
else if ( sin(angle) < -THRES)
J |= VBA_DOWN;
}
#endif
return J;
}
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
// inside the 'valid direction' block.
double angle = atan2(wm_ay, wm_ax);
const double THRES = 1.0 / sqrt(2.0);
if ( cos(angle) > THRES )
J |= VBA_RIGHT;
else if ( cos(angle) < -THRES )
J |= VBA_LEFT;
if ( sin(angle) > THRES )
J |= VBA_UP;
else if ( sin(angle) < -THRES)
J |= VBA_DOWN;
}|
Re: VbaGX Input Code Fix January 26, 2012 02:24AM | Registered: 14 years ago Posts: 4 |
static void decodepad (int chan)
{
int i, offset;
float t;
s8 pad_x = userInput[chan].pad.stickX;
s8 pad_y = userInput[chan].pad.stickY;
u32 jp = userInput[chan].pad.btns_h;
#ifdef HW_RVL
s8 wm_ax = userInput[chan].WPAD_StickX(0);
s8 wm_ay = userInput[chan].WPAD_StickY(0);
u32 wp = userInput[chan].wpad->btns_h;
u32 exp_type;
if ( WPAD_Probe(chan, &exp_type) != 0 )
exp_type = WPAD_EXP_NONE;
#endif
/***
Gamecube Joystick input
***/
// Is XY inside the "zone"?
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
{
/*** we don't want division by zero ***/
if (pad_x > 0 && pad_y == 0)
jp |= PAD_BUTTON_RIGHT;
if (pad_x < 0 && pad_y == 0)
jp |= PAD_BUTTON_LEFT;
if (pad_x == 0 && pad_y > 0)
jp |= PAD_BUTTON_UP;
if (pad_x == 0 && pad_y < 0)
jp |= PAD_BUTTON_DOWN;
if (pad_x != 0 && pad_y != 0)
{
/*** Recalc left / right ***/
t = (float) pad_y / pad_x;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (pad_x >= 0)
jp |= PAD_BUTTON_RIGHT;
else
jp |= PAD_BUTTON_LEFT;
}
/*** Recalc up / down ***/
t = (float) pad_x / pad_y;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (pad_y >= 0)
jp |= PAD_BUTTON_UP;
else
jp |= PAD_BUTTON_DOWN;
}
}
}
#ifdef HW_RVL
/***
Wii Joystick (classic, nunchuk) input
***/
// Is XY inside the "zone"?
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
// inside the 'valid direction' block.
double angle = atan2(wm_ay, wm_ax);
const double THRES = 1.0 / sqrt(2.0);
if ( cos(angle) > THRES )
wp |= (exp_type == WPAD_EXP_CLASSIC) ? WPAD_CLASSIC_BUTTON_RIGHT : WPAD_BUTTON_RIGHT;
else if ( cos(angle) < -THRES )
wp |= (exp_type == WPAD_EXP_CLASSIC) ? WPAD_CLASSIC_BUTTON_LEFT : WPAD_BUTTON_LEFT;
if ( sin(angle) > THRES )
wp |= (exp_type == WPAD_EXP_CLASSIC) ? WPAD_CLASSIC_BUTTON_UP : WPAD_BUTTON_UP;
else if ( sin(angle) < -THRES)
wp |= (exp_type == WPAD_EXP_CLASSIC) ? WPAD_CLASSIC_BUTTON_DOWN : WPAD_BUTTON_DOWN;
}
#endif
/*** Fix offset to pad ***/
offset = ((chan + 1) << 4);
/*** Report pressed buttons (gamepads) ***/
for (i = 0; i < MAXJP; i++)
{
if ( (jp & btnmap[CTRL_PAD][CTRLR_GCPAD]) // gamecube controller
#ifdef HW_RVL
|| ( (exp_type == WPAD_EXP_NONE) && (wp & btnmap[CTRL_PAD][CTRLR_WIIMOTE]) ) // wiimote
|| ( (exp_type == WPAD_EXP_CLASSIC) && (wp & btnmap[CTRL_PAD][CTRLR_CLASSIC]) ) // classic controller
|| ( (exp_type == WPAD_EXP_NUNCHUK) && (wp & btnmap[CTRL_PAD][CTRLR_NUNCHUK]) ) // nunchuk + wiimote
#endif
)
S9xReportButton (offset + i, true);
else
S9xReportButton (offset + i, false);
}
/*** Superscope ***/
if (Settings.SuperScopeMaster && chan == 0) // report only once
{
// buttons
offset = 0x50;
for (i = 0; i < 6; i++)
{
if (jp & btnmap[CTRL_SCOPE][CTRLR_GCPAD]
#ifdef HW_RVL
|| wp & btnmap[CTRL_SCOPE][CTRLR_WIIMOTE]
#endif
)
{
if(i == 3 || i == 4) // turbo
{
if((i == 3 && scopeTurbo == 1) || // turbo ON already, don't change
(i == 4 && scopeTurbo == 0)) // turbo OFF already, don't change
{
S9xReportButton(offset + i, false);
}
else // turbo changed to ON or OFF
{
scopeTurbo = 4-i;
S9xReportButton(offset + i, true);
}
}
else
S9xReportButton(offset + i, true);
}
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x80;
UpdateCursorPosition(chan, cursor_x[0], cursor_y[0]);
S9xReportPointer(offset, (u16) cursor_x[0], (u16) cursor_y[0]);
}
/*** Mouse ***/
else if (Settings.MouseMaster && chan == 0)
{
// buttons
offset = 0x60 + (2 * chan);
for (i = 0; i < 2; i++)
{
if (jp & btnmap[CTRL_MOUSE][CTRLR_GCPAD]
#ifdef HW_RVL
|| wp & btnmap[CTRL_MOUSE][CTRLR_WIIMOTE]
#endif
)
S9xReportButton(offset + i, true);
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x81;
UpdateCursorPosition(chan, cursor_x[1 + chan], cursor_y[1 + chan]);
S9xReportPointer(offset + chan, (u16) cursor_x[1 + chan],
(u16) cursor_y[1 + chan]);
}
/*** Justifier ***/
else if (Settings.JustifierMaster && chan < 2)
{
// buttons
offset = 0x70 + (3 * chan);
for (i = 0; i < 3; i++)
{
if (jp & btnmap[CTRL_JUST][CTRLR_GCPAD]
#ifdef HW_RVL
|| wp & btnmap[CTRL_JUST][CTRLR_WIIMOTE]
#endif
)
S9xReportButton(offset + i, true);
else
S9xReportButton(offset + i, false);
}
// pointer
offset = 0x83;
UpdateCursorPosition(chan, cursor_x[3 + chan], cursor_y[3 + chan]);
S9xReportPointer(offset + chan, (u16) cursor_x[3 + chan],
(u16) cursor_y[3 + chan]);
}
#ifdef HW_RVL
// screenshot (temp)
if (wp & CLASSIC_CTRL_BUTTON_ZR)
S9xReportButton(0x90, true);
else
S9xReportButton(0x90, false);
#endif
}
|
Re: VbaGX Input Code Fix January 26, 2012 05:13AM | Moderator Registered: 16 years ago Posts: 686 |
|
Re: VbaGX Input Code Fix January 26, 2012 10:21AM | Registered: 14 years ago Posts: 4 |
Point p = new Point(0, -100);
double Angle = Math.Atan2(p.Y, p.X);
double Thresh = 1.0 / Math.Sqrt(2.0);
if ( Math.Cos(Angle) > Thresh )
Console.WriteLine("Right");
else if ( Math.Cos(Angle) < -Thresh )
Console.WriteLine("Left");
else if ( Math.Sin(Angle) > Thresh )
Console.WriteLine("Up");
else if ( Math.Sin(Angle) < -Thresh)
Console.WriteLine("Down");
double Result1 = Math.Sin(Angle);
double Result2 = Math.Cos(Angle);
Console.WriteLine(String.Format("Angle: {0}\n Sin: {1}\n Cos: {2}\n Threshold: {3}\n", Angle, Result1, Result2, Thresh));Down Angle: -1.5707963267949 Sin: -1 Cos: 6.12303176911189E-17 Threshold: 0.707106781186547
|
Re: VbaGX Input Code Fix January 27, 2012 08:25PM | Registered: 14 years ago Posts: 4 |
|
Re: VbaGX Input Code Fix February 02, 2012 02:02AM | Registered: 15 years ago Posts: 282 |
Quote
tueidj
This seems kind of backwards; you start with wm_ax and wm_ay which you use to find the angle, then you take the sine and cosine... doesn't that just give you back the original wm_ax and wm_ay values?
|
Re: VbaGX Input Code Fix February 02, 2012 03:44AM | Moderator Registered: 16 years ago Posts: 686 |
Quote
Axel
There is a flaw in your math logic. The sine and cosine of an angle don't give you the value of X and Y, it gives you a decimal value between -1 and 1.
1) The inverse Tan of x/y gives you the angle
2) The sine of the angle gives you a value between -1 (full down) and 1 (full up)
3) The cosine of the angle gives you a value between -1 (full left) and 1 (full right)
4) The Threshold calculated is a 45 degrees angle (1 / square root of 2). If the joystick has an inclination of more than 45 degrees in any direction, it activates the press of that direction.
I hope this explanation makes it clearer on why this new approach works.
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)It's not checking an angle or "inclination", it's the magnitude of the stick compared to the center position i.e. if the stick has been pushed far enough to register as a digital movement.