Nunchuk: Hardcode Nunchuk stick calibration values

The game can never change these, so there's no reason to make it
dynamic. Just put the constants in the code.

While we're at it, take the time to clean up the code and also
and document several of the hacks we're doing inside to make the code
clearer to understand.
This commit is contained in:
Jasper St. Pierre 2014-09-04 19:31:18 -07:00
parent 64014d1dcd
commit 211eafc130
3 changed files with 39 additions and 60 deletions

View File

@ -15,11 +15,6 @@ static const u8 nunchuk_calibration[] =
{
0x80, 0x80, 0x80, 0x00, // accelerometer x, y, z neutral
0xb3, 0xb3, 0xb3, 0x00, // x, y, z g-force values
// 0x80 = analog stick x and y axis center
0xff, 0x00, 0x80,
0xff, 0x00, 0x80,
0xec, 0x41 // checksum on the last two bytes
};
static const u8 nunchuk_button_bitmasks[] =
@ -66,35 +61,26 @@ void Nunchuk::GetState(u8* const data)
ncdata->bt.hex = 0;
// stick
double state[2];
m_stick->GetState(&state[0], &state[1]);
double jx, jy;
m_stick->GetState(&jx, &jy);
nu_cal &cal = *(nu_cal*)&reg.calibration;
nu_js cal_js[2];
cal_js[0] = cal.jx;
cal_js[1] = cal.jy;
ncdata->jx = u8(STICK_CENTER + jx * STICK_RADIUS);
ncdata->jy = u8(STICK_CENTER + jy * STICK_RADIUS);
for (int i = 0; i < 2; i++)
// Some terribly coded games check whether to move with a check like
//
// if (x != 0 && y != 0)
// do_movement(x, y);
//
// With keyboard controls, these games break if you simply hit
// of the axes. Adjust this if you're hitting one of the axes so that
// we slightly tweak the other axis.
if (ncdata->jx != STICK_CENTER || ncdata->jy != STICK_CENTER)
{
double &s = state[i];
nu_js c = cal_js[i];
if (s < 0)
s = s * abs(c.min - c.center) + c.center;
else if (s > 0)
s = s * abs(c.max - c.center) + c.center;
else
s = c.center;
}
ncdata->jx = u8(trim(state[0]));
ncdata->jy = u8(trim(state[1]));
if (ncdata->jx != cal.jx.center || ncdata->jy != cal.jy.center)
{
if (ncdata->jy == cal.jy.center)
ncdata->jy = cal.jy.center + 1;
if (ncdata->jx == cal.jx.center)
ncdata->jx = cal.jx.center + 1;
if (ncdata->jx == STICK_CENTER)
++ncdata->jx;
if (ncdata->jy == STICK_CENTER)
++ncdata->jy;
}
AccelData accel;
@ -112,25 +98,25 @@ void Nunchuk::GetState(u8* const data)
// flip the button bits :/
ncdata->bt.hex ^= 0x03;
accel_cal& calib = cal.cal;
accel_cal& calib = *(accel_cal*)&reg.calibration;
u16 x = (u16)(accel.x * (calib.one_g.x - calib.zero_g.x) + calib.zero_g.x);
u16 y = (u16)(accel.y * (calib.one_g.y - calib.zero_g.y) + calib.zero_g.y);
u16 z = (u16)(accel.z * (calib.one_g.z - calib.zero_g.z) + calib.zero_g.z);
u16 accel_x = (u16)(accel.x * (calib.one_g.x - calib.zero_g.x) + calib.zero_g.x);
u16 accel_y = (u16)(accel.y * (calib.one_g.y - calib.zero_g.y) + calib.zero_g.y);
u16 accel_z = (u16)(accel.z * (calib.one_g.z - calib.zero_g.z) + calib.zero_g.z);
if (x > 1024)
x = 1024;
if (y > 1024)
y = 1024;
if (z > 1024)
z = 1024;
if (accel_x > 1024)
accel_x = 1024;
if (accel_y > 1024)
accel_y = 1024;
if (accel_z > 1024)
accel_z = 1024;
ncdata->ax = x & 0xFF;
ncdata->ay = y & 0xFF;
ncdata->az = z & 0xFF;
ncdata->passthrough_data.acc_x_lsb = x >> 8 & 0x3;
ncdata->passthrough_data.acc_y_lsb = y >> 8 & 0x3;
ncdata->passthrough_data.acc_z_lsb = z >> 8 & 0x3;
ncdata->ax = accel_x & 0xFF;
ncdata->ay = accel_y & 0xFF;
ncdata->az = accel_z & 0xFF;
ncdata->passthrough_data.acc_x_lsb = accel_x >> 8 & 0x3;
ncdata->passthrough_data.acc_y_lsb = accel_y >> 8 & 0x3;
ncdata->passthrough_data.acc_z_lsb = accel_z >> 8 & 0x3;
}
void Nunchuk::LoadDefaults(const ControllerInterface& ciface)

View File

@ -22,6 +22,12 @@ public:
BUTTON_Z = 0x01,
};
enum
{
STICK_CENTER = 0x80,
STICK_RADIUS = 0x7F,
};
void LoadDefaults(const ControllerInterface& ciface) override;
private:

View File

@ -520,17 +520,4 @@ struct accel_cal
static_assert(sizeof(accel_cal) == 8, "acceleration data needs needs to be 8 bytes");
struct nu_js
{
u8 max, min, center;
};
struct nu_cal
{
accel_cal cal;
nu_js jx;
nu_js jy;
u8 sum[2];
};
#pragma pack(pop)