WiimoteEmu: Nunchuk and Classic Controller calibration accuracy improvements.

This commit is contained in:
Jordan Woyak 2020-01-06 09:52:50 -06:00
parent 04e9279f3d
commit d9bd714143
4 changed files with 31 additions and 37 deletions

View File

@ -84,7 +84,7 @@ Classic::Classic() : Extension1stParty("Classic", _trans("Classic Controller"))
}
// sticks
constexpr auto gate_radius = ControlState(STICK_GATE_RADIUS) / LEFT_STICK_RADIUS;
constexpr auto gate_radius = ControlState(STICK_GATE_RADIUS) / CAL_STICK_RANGE;
groups.emplace_back(m_left_stick =
new ControllerEmu::OctagonAnalogStick(_trans("Left Stick"), gate_radius));
groups.emplace_back(
@ -115,20 +115,16 @@ void Classic::Update()
{
const ControllerEmu::AnalogStick::StateData left_stick_state = m_left_stick->GetState();
classic_data.lx = static_cast<u8>(Classic::LEFT_STICK_CENTER_X +
(left_stick_state.x * Classic::LEFT_STICK_RADIUS));
classic_data.ly = static_cast<u8>(Classic::LEFT_STICK_CENTER_Y +
(left_stick_state.y * Classic::LEFT_STICK_RADIUS));
classic_data.lx = static_cast<u8>(LEFT_STICK_CENTER + (left_stick_state.x * LEFT_STICK_RADIUS));
classic_data.ly = static_cast<u8>(LEFT_STICK_CENTER + (left_stick_state.y * LEFT_STICK_RADIUS));
}
// right stick
{
const ControllerEmu::AnalogStick::StateData right_stick_data = m_right_stick->GetState();
const u8 x = static_cast<u8>(Classic::RIGHT_STICK_CENTER_X +
(right_stick_data.x * Classic::RIGHT_STICK_RADIUS));
const u8 y = static_cast<u8>(Classic::RIGHT_STICK_CENTER_Y +
(right_stick_data.y * Classic::RIGHT_STICK_RADIUS));
const u8 x = static_cast<u8>(RIGHT_STICK_CENTER + (right_stick_data.x * RIGHT_STICK_RADIUS));
const u8 y = static_cast<u8>(RIGHT_STICK_CENTER + (right_stick_data.y * RIGHT_STICK_RADIUS));
classic_data.rx1 = x;
classic_data.rx2 = x >> 1;
@ -141,8 +137,8 @@ void Classic::Update()
ControlState trigs[2] = {0, 0};
m_triggers->GetState(&classic_data.bt.hex, classic_trigger_bitmasks.data(), trigs);
const u8 lt = static_cast<u8>(trigs[0] * Classic::LEFT_TRIGGER_RANGE);
const u8 rt = static_cast<u8>(trigs[1] * Classic::RIGHT_TRIGGER_RANGE);
const u8 lt = static_cast<u8>(trigs[0] * TRIGGER_RANGE);
const u8 rt = static_cast<u8>(trigs[1] * TRIGGER_RANGE);
classic_data.lt1 = lt;
classic_data.lt2 = lt >> 3;
@ -177,26 +173,27 @@ void Classic::Reset()
m_reg.identifier = classic_id;
// Build calibration data:
// All values are to 8 bits of precision.
m_reg.calibration = {{
// Left Stick X max,min,center:
CAL_STICK_CENTER + CAL_STICK_RANGE,
CAL_STICK_CENTER - CAL_STICK_RANGE,
CAL_STICK_CENTER + STICK_GATE_RADIUS,
CAL_STICK_CENTER - STICK_GATE_RADIUS,
CAL_STICK_CENTER,
// Left Stick Y max,min,center:
CAL_STICK_CENTER + CAL_STICK_RANGE,
CAL_STICK_CENTER - CAL_STICK_RANGE,
CAL_STICK_CENTER + STICK_GATE_RADIUS,
CAL_STICK_CENTER - STICK_GATE_RADIUS,
CAL_STICK_CENTER,
// Right Stick X max,min,center:
CAL_STICK_CENTER + CAL_STICK_RANGE,
CAL_STICK_CENTER - CAL_STICK_RANGE,
CAL_STICK_CENTER + STICK_GATE_RADIUS,
CAL_STICK_CENTER - STICK_GATE_RADIUS,
CAL_STICK_CENTER,
// Right Stick Y max,min,center:
CAL_STICK_CENTER + CAL_STICK_RANGE,
CAL_STICK_CENTER - CAL_STICK_RANGE,
CAL_STICK_CENTER + STICK_GATE_RADIUS,
CAL_STICK_CENTER - STICK_GATE_RADIUS,
CAL_STICK_CENTER,
// Left/Right trigger range: (assumed based on real calibration data values)
LEFT_TRIGGER_RANGE,
RIGHT_TRIGGER_RANGE,
// Left/Right trigger neutrals.
0,
0,
// 2 checksum bytes calculated below:
0x00,
0x00,

View File

@ -105,26 +105,22 @@ public:
static constexpr u16 PAD_LEFT = 0x0200;
static constexpr u16 PAD_UP = 0x0100;
// Typical value pulled from physical Classic Controller.
static constexpr u8 STICK_GATE_RADIUS = 0x61;
static constexpr u8 CAL_STICK_CENTER = 0x80;
static constexpr u8 CAL_STICK_RANGE = 0x7f;
static constexpr int CAL_STICK_BITS = 8;
static constexpr int LEFT_STICK_BITS = 6;
static constexpr u8 LEFT_STICK_CENTER_X = CAL_STICK_CENTER >> (CAL_STICK_BITS - LEFT_STICK_BITS);
static constexpr u8 LEFT_STICK_CENTER_Y = CAL_STICK_CENTER >> (CAL_STICK_BITS - LEFT_STICK_BITS);
static constexpr u8 LEFT_STICK_CENTER = CAL_STICK_CENTER >> (CAL_STICK_BITS - LEFT_STICK_BITS);
static constexpr u8 LEFT_STICK_RADIUS = CAL_STICK_RANGE >> (CAL_STICK_BITS - LEFT_STICK_BITS);
static constexpr int RIGHT_STICK_BITS = 5;
static constexpr u8 RIGHT_STICK_CENTER_X = CAL_STICK_CENTER >>
(CAL_STICK_BITS - RIGHT_STICK_BITS);
static constexpr u8 RIGHT_STICK_CENTER_Y = CAL_STICK_CENTER >>
(CAL_STICK_BITS - RIGHT_STICK_BITS);
static constexpr u8 RIGHT_STICK_CENTER = CAL_STICK_CENTER >> (CAL_STICK_BITS - RIGHT_STICK_BITS);
static constexpr u8 RIGHT_STICK_RADIUS = CAL_STICK_RANGE >> (CAL_STICK_BITS - RIGHT_STICK_BITS);
static constexpr u8 LEFT_TRIGGER_RANGE = 0x1F;
static constexpr u8 RIGHT_TRIGGER_RANGE = 0x1F;
static constexpr u8 STICK_GATE_RADIUS = 0x16;
static constexpr u8 TRIGGER_RANGE = 0x1F;
private:
ControllerEmu::Buttons* m_buttons;

View File

@ -144,12 +144,12 @@ void Nunchuk::Reset()
// Possibly LSBs of 1G values:
0x00,
// Stick X max,min,center:
STICK_CENTER + STICK_RADIUS,
STICK_CENTER - STICK_RADIUS,
STICK_CENTER + STICK_GATE_RADIUS,
STICK_CENTER - STICK_GATE_RADIUS,
STICK_CENTER,
// Stick Y max,min,center:
STICK_CENTER + STICK_RADIUS,
STICK_CENTER - STICK_RADIUS,
STICK_CENTER + STICK_GATE_RADIUS,
STICK_CENTER - STICK_GATE_RADIUS,
STICK_CENTER,
// 2 checksum bytes calculated below:
0x00,

View File

@ -81,12 +81,13 @@ public:
static constexpr u8 BUTTON_C = 0x02;
static constexpr u8 BUTTON_Z = 0x01;
// Typical values pulled from physical Nunchuk.
static constexpr u8 ACCEL_ZERO_G = 0x80;
static constexpr u8 ACCEL_ONE_G = 0xB3;
static constexpr u8 STICK_GATE_RADIUS = 0x60;
static constexpr u8 STICK_CENTER = 0x80;
static constexpr u8 STICK_RADIUS = 0x7F;
static constexpr u8 STICK_GATE_RADIUS = 0x52;
void LoadDefaults(const ControllerInterface& ciface) override;