Classic controllers returning invalid calibration data
Posted: Fri Jul 11, 2014 3:26 pm
It seems that most problems with 3rd party Classic Controllers in libogc/libwiiuse are caused by controllers that do not return valid calibration data during the initialization handshake.
The probleme is that there is actually no double-check in libwiiuse to see if acquired data is valid and the following code in dynamics.c can actually cause "Division by Zero" exception when the returned data is fixed to 0xFFF (which seems to be the case with those unsupported controllers):
A quick solution would be to change the following code in classics.c :
to
The probleme is that there is actually no double-check in libwiiuse to see if acquired data is valid and the following code in dynamics.c can actually cause "Division by Zero" exception when the returned data is fixed to 0xFFF (which seems to be the case with those unsupported controllers):
Code: Select all
if (x == js->center.x)
rx = 0;
else if (x >= js->center.x)
rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x));
else
rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f;
if (y == js->center.y)
ry = 0;
else if (y >= js->center.y)
ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y));
else
ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f;
Code: Select all
/* joystick stuff */
cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
cc->ljs.min.x = data[1 + offset] / 4;
cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
cc->ljs.min.y = data[4 + offset] / 4;
cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
cc->rjs.min.x = data[7 + offset] / 8;
cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
cc->rjs.min.y = data[10 + offset] / 8;
cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;
Code: Select all
/* joystick stuff */
if (data[offset] = 0xFF)
{
/* invalid calibration data : set sefault values */
cc->ljs.max.x = cc->ljs.max.y =64;
cc->ljs.min.x = cc->ljs.min.y =0;
cc->ljs.center.x = cc->ljs.center.y =32;
cc->rjs.max.x = cc->rjs.max.y = 32;
cc->rjs.min.x = cc->rjs.min.y = 0;
cc->rjs.center.x = cc->rjs.center.y = 16;
}
else
{
cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
cc->ljs.min.x = data[1 + offset] / 4;
cc->ljs.center.x = data[2 + offset] / 4 == 0 ? 32 : data[2 + offset] / 4;
cc->ljs.max.y = data[3 + offset] / 4 == 0 ? 64 : data[3 + offset] / 4;
cc->ljs.min.y = data[4 + offset] / 4;
cc->ljs.center.y = data[5 + offset] / 4 == 0 ? 32 : data[5 + offset] / 4;
cc->rjs.max.x = data[6 + offset] / 8 == 0 ? 32 : data[6 + offset] / 8;
cc->rjs.min.x = data[7 + offset] / 8;
cc->rjs.center.x = data[8 + offset] / 8 == 0 ? 16 : data[8 + offset] / 8;
cc->rjs.max.y = data[9 + offset] / 8 == 0 ? 32 : data[9 + offset] / 8;
cc->rjs.min.y = data[10 + offset] / 8;
cc->rjs.center.y = data[11 + offset] / 8 == 0 ? 16 : data[11 + offset] / 8;
}