Adding Nunchuk stick calibration

because it's useful for the hybrid Wiimote mode
This commit is contained in:
John Peterson 2013-07-13 01:12:51 +02:00 committed by Rachel Bryk
parent 4aba0135e1
commit 23f59a82f7
16 changed files with 119 additions and 77 deletions

View File

@ -13,15 +13,17 @@ static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
// The id for a partially inserted extension
static const u8 partially_id[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff };
Attachment::Attachment( const char* const _name ) : name( _name )
Attachment::Attachment( const char* const _name, WiimoteEmu::ExtensionReg& _reg )
: name( _name ), reg( _reg )
{
reg.resize( WIIMOTE_REG_EXT_SIZE, 0);
memset(id, 0, sizeof(id));
memset(calibration, 0, sizeof(calibration));
}
None::None() : Attachment( "None" )
None::None( WiimoteEmu::ExtensionReg& _reg ) : Attachment( "None", _reg )
{
// set up register
memcpy( &reg[0xfa], nothing_id, sizeof(nothing_id) );
memcpy(&id, nothing_id, sizeof(nothing_id));
}
std::string Attachment::GetName() const
@ -29,6 +31,14 @@ std::string Attachment::GetName() const
return name;
}
void Attachment::Reset()
{
// set up register
memset( &reg, 0, WIIMOTE_REG_EXT_SIZE );
memcpy( &reg.constant_id, id, sizeof(id) );
memcpy( &reg.calibration, calibration, sizeof(calibration) );
}
}
void ControllerEmu::Extension::GetState( u8* const data, const bool focus )

View File

@ -14,19 +14,23 @@ namespace WiimoteEmu
class Attachment : public ControllerEmu
{
public:
Attachment( const char* const _name );
Attachment( const char* const _name, WiimoteEmu::ExtensionReg& _reg );
virtual void GetState( u8* const data, const bool focus = true ) {}
void Reset();
std::string GetName() const;
const char* const name;
std::vector<u8> reg;
const char* const name;
WiimoteEmu::ExtensionReg& reg;
u8 id[6];
u8 calibration[0x10];
};
class None : public Attachment
{
public:
None();
None( WiimoteEmu::ExtensionReg& _reg );
};
}

View File

@ -53,7 +53,7 @@ static const u16 classic_dpad_bitmasks[] =
Classic::PAD_UP, Classic::PAD_DOWN, Classic::PAD_LEFT, Classic::PAD_RIGHT
};
Classic::Classic() : Attachment(_trans("Classic"))
Classic::Classic(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Classic"), _reg)
{
// buttons
groups.push_back(m_buttons = new Buttons("Buttons"));
@ -76,9 +76,9 @@ Classic::Classic() : Attachment(_trans("Classic"))
// set up register
// calibration
memcpy(&reg[0x20], classic_calibration, sizeof(classic_calibration));
memcpy(&calibration, classic_calibration, sizeof(classic_calibration));
// id
memcpy(&reg[0xfa], classic_id, sizeof(classic_id));
memcpy(&id, classic_id, sizeof(classic_id));
}
void Classic::GetState(u8* const data, const bool focus)

View File

@ -10,7 +10,7 @@ namespace WiimoteEmu
class Classic : public Attachment
{
public:
Classic();
Classic(WiimoteEmu::ExtensionReg& _reg);
void GetState( u8* const data, const bool focus );
enum

View File

@ -32,7 +32,7 @@ static const u16 drum_button_bitmasks[] =
Drums::BUTTON_PLUS,
};
Drums::Drums() : Attachment(_trans("Drums"))
Drums::Drums(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Drums"), _reg)
{
// pads
groups.push_back(m_pads = new Buttons(_trans("Pads")));
@ -49,7 +49,7 @@ Drums::Drums() : Attachment(_trans("Drums"))
// set up register
// id
memcpy(&reg[0xfa], drums_id, sizeof(drums_id));
memcpy(&id, drums_id, sizeof(drums_id));
}
void Drums::GetState(u8* const data, const bool focus)

View File

@ -10,7 +10,7 @@ namespace WiimoteEmu
class Drums : public Attachment
{
public:
Drums();
Drums(WiimoteEmu::ExtensionReg& _reg);
void GetState( u8* const data, const bool focus );
enum

View File

@ -36,7 +36,7 @@ static const u16 guitar_strum_bitmasks[] =
Guitar::BAR_DOWN,
};
Guitar::Guitar() : Attachment(_trans("Guitar"))
Guitar::Guitar(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Guitar"), _reg)
{
// frets
groups.push_back(m_frets = new Buttons(_trans("Frets")));
@ -62,7 +62,7 @@ Guitar::Guitar() : Attachment(_trans("Guitar"))
// set up register
// id
memcpy(&reg[0xfa], guitar_id, sizeof(guitar_id));
memcpy(&id, guitar_id, sizeof(guitar_id));
}
void Guitar::GetState(u8* const data, const bool focus)

View File

@ -10,7 +10,7 @@ namespace WiimoteEmu
class Guitar : public Attachment
{
public:
Guitar();
Guitar(WiimoteEmu::ExtensionReg& _reg);
void GetState( u8* const data, const bool focus );
enum

View File

@ -31,7 +31,8 @@ static const u8 nunchuk_button_bitmasks[] =
Nunchuk::BUTTON_Z,
};
Nunchuk::Nunchuk(UDPWrapper *wrp) : Attachment(_trans("Nunchuk")) , m_udpWrap(wrp)
Nunchuk::Nunchuk(UDPWrapper *wrp, WiimoteEmu::ExtensionReg& _reg)
: Attachment(_trans("Nunchuk"), _reg) , m_udpWrap(wrp)
{
// buttons
groups.push_back(m_buttons = new Buttons("Buttons"));
@ -55,9 +56,9 @@ Nunchuk::Nunchuk(UDPWrapper *wrp) : Attachment(_trans("Nunchuk")) , m_udpWrap(wr
// set up register
// calibration
memcpy(&reg[0x20], nunchuck_calibration, sizeof(nunchuck_calibration));
memcpy(&calibration, nunchuck_calibration, sizeof(nunchuck_calibration));
// id
memcpy(&reg[0xfa], nunchuck_id, sizeof(nunchuck_id));
memcpy(&id, nunchuck_id, sizeof(nunchuck_id));
// this should get set to 0 on disconnect, but it isn't, o well
memset(m_shake_step, 0, sizeof(m_shake_step));
@ -68,11 +69,37 @@ void Nunchuk::GetState(u8* const data, const bool focus)
wm_extension* const ncdata = (wm_extension*)data;
ncdata->bt = 0;
// stick / not using calibration data for stick, o well
m_stick->GetState(&ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0);
// stick
ControlState state[2];
m_stick->GetState(&state[0], &state[1], 0, 1);
nu_cal &cal = *(nu_cal*)&reg.calibration;
nu_js cal_js[2];
cal_js[0] = *&cal.jx;
cal_js[1] = *&cal.jy;
for (int i = 0; i < 2; i++) {
ControlState &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 (!focus)
{
ncdata->jx = cal.jx.center;
ncdata->jy = cal.jy.center;
}
AccelData accel;
accel_cal* calib = (accel_cal*)&reg[0x20];
accel_cal* calib = (accel_cal*)&reg.calibration[0];
// tilt
EmulateTilt(&accel, m_tilt, focus);

View File

@ -15,7 +15,7 @@ namespace WiimoteEmu
class Nunchuk : public Attachment
{
public:
Nunchuk(UDPWrapper * wrp);
Nunchuk(UDPWrapper * wrp, WiimoteEmu::ExtensionReg& _reg);
virtual void GetState( u8* const data, const bool focus );

View File

@ -30,7 +30,7 @@ static const char* const turntable_button_names[] =
"-", "+", _trans("Euphoria"),
};
Turntable::Turntable() : Attachment(_trans("Turntable"))
Turntable::Turntable(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Turntable"), _reg)
{
// buttons
groups.push_back(m_buttons = new Buttons("Buttons"));
@ -53,7 +53,7 @@ Turntable::Turntable() : Attachment(_trans("Turntable"))
// set up register
// id
memcpy(&reg[0xfa], turntable_id, sizeof(turntable_id));
memcpy(&id, turntable_id, sizeof(turntable_id));
}
void Turntable::GetState(u8* const data, const bool focus)

View File

@ -10,7 +10,7 @@ namespace WiimoteEmu
class Turntable : public Attachment
{
public:
Turntable();
Turntable(WiimoteEmu::ExtensionReg& _reg);
void GetState(u8* const data, const bool focus);
enum

View File

@ -851,11 +851,8 @@ void Wiimote::HandleExtensionSwap()
// set the wanted extension
m_extension->active_extension = m_extension->switch_extension;
// set register, I hate this
const std::vector<u8> &reg = ((WiimoteEmu::Attachment*)m_extension->attachments[m_extension->active_extension])->reg;
memset(&m_reg_ext, 0, WIIMOTE_REG_EXT_SIZE);
memcpy(&m_reg_ext, &reg[0], reg.size());
// reset register
((WiimoteEmu::Attachment*)m_extension->attachments[m_extension->active_extension])->Reset();
}
}

View File

@ -286,12 +286,12 @@ Wiimote::Wiimote( const unsigned int index )
// extension
groups.push_back(m_extension = new Extension(_trans("Extension")));
m_extension->attachments.push_back(new WiimoteEmu::None());
m_extension->attachments.push_back(new WiimoteEmu::Nunchuk(m_udp));
m_extension->attachments.push_back(new WiimoteEmu::Classic());
m_extension->attachments.push_back(new WiimoteEmu::Guitar());
m_extension->attachments.push_back(new WiimoteEmu::Drums());
m_extension->attachments.push_back(new WiimoteEmu::Turntable());
m_extension->attachments.push_back(new WiimoteEmu::None(m_reg_ext));
m_extension->attachments.push_back(new WiimoteEmu::Nunchuk(m_udp, m_reg_ext));
m_extension->attachments.push_back(new WiimoteEmu::Classic(m_reg_ext));
m_extension->attachments.push_back(new WiimoteEmu::Guitar(m_reg_ext));
m_extension->attachments.push_back(new WiimoteEmu::Drums(m_reg_ext));
m_extension->attachments.push_back(new WiimoteEmu::Turntable(m_reg_ext));
m_extension->settings.push_back(new ControlGroup::Setting(_trans("Motion Plus"), 0, 0, 1));

View File

@ -17,7 +17,7 @@
#include <vector>
#include <queue>
// Registry sizes
// Registry sizes
#define WIIMOTE_EEPROM_SIZE (16*1024)
#define WIIMOTE_EEPROM_FREE_SIZE 0x1700
#define WIIMOTE_REG_SPEAKER_SIZE 10
@ -47,6 +47,30 @@ struct ADPCMState
s32 predictor, step;
};
struct ExtensionReg
{
u8 unknown1[0x08];
// address 0x08
u8 controller_data[0x06];
u8 unknown2[0x12];
// address 0x20
u8 calibration[0x10];
u8 unknown3[0x10];
// address 0x40
u8 encryption_key[0x10];
u8 unknown4[0xA0];
// address 0xF0
u8 encryption;
u8 unknown5[0x9];
// address 0xFA
u8 constant_id[6];
};
extern const ReportFeatures reporting_mode_features[];
void EmulateShake(AccelData* const accel_data
@ -143,7 +167,7 @@ private:
ControlGroup* m_rumble;
Extension* m_extension;
ControlGroup* m_options;
// WiiMote accel data
AccelData m_accel;
@ -151,7 +175,7 @@ private:
const u8 m_index;
double ir_sin, ir_cos; //for the low pass filter
UDPWrapper* m_udp;
bool m_rumble_on;
@ -201,30 +225,7 @@ private:
} m_reg_ir;
struct ExtensionReg
{
u8 unknown1[0x08];
// address 0x08
u8 controller_data[0x06];
u8 unknown2[0x12];
// address 0x20
u8 calibration[0x10];
u8 unknown3[0x10];
// address 0x40
u8 encryption_key[0x10];
u8 unknown4[0xA0];
// address 0xF0
u8 encryption;
u8 unknown5[0x9];
// address 0xFA
u8 constant_id[6];
} m_reg_ext;
ExtensionReg m_reg_ext;
struct SpeakerReg
{

View File

@ -54,7 +54,7 @@ struct wm_ir_basic
};
// Three bytes for one object
struct wm_ir_extended
struct wm_ir_extended
{
u8 x;
u8 y;
@ -150,9 +150,9 @@ struct wm_turntable_extension
struct wm_motionplus_data
{
u8 yaw1;
u8 roll1;
u8 pitch1;
u8 yaw2 : 6;
@ -230,7 +230,7 @@ struct wm_status_report
};
#define WM_WRITE_DATA 0x16
struct wm_write_data
struct wm_write_data
{
u8 rumble : 1;
u8 space : 2; //see WM_SPACE_*
@ -241,7 +241,7 @@ struct wm_write_data
};
#define WM_ACK_DATA 0x22
struct wm_acknowledge
struct wm_acknowledge
{
wm_core buttons;
u8 reportID;
@ -276,7 +276,7 @@ struct wm_read_data_reply
#define WM_RDERR_WOREG 7
#define WM_RDERR_NOMEM 8
// Data reports
#define WM_REPORT_CORE 0x30
@ -304,20 +304,20 @@ struct wm_report_core_accel_ir12
#define WM_REPORT_CORE_EXT19 0x34
#define WM_REPORT_CORE_ACCEL_EXT16 0x35
struct wm_report_core_accel_ext16
struct wm_report_core_accel_ext16
{
wm_core c;
wm_accel a;
wm_extension ext;
//wm_ir_basic ir[2];
u8 pad[10];
};
#define WM_REPORT_CORE_IR10_EXT9 0x36
#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37
struct wm_report_core_accel_ir10_ext6
struct wm_report_core_accel_ir10_ext6
{
wm_core c;
wm_accel a;
@ -336,7 +336,7 @@ struct wm_report_ext21
#define WM_REPORT_INTERLEAVE2 0x3f
#define WM_SPEAKER_ENABLE 0x14
#define WM_SPEAKER_MUTE 0x19
#define WM_SPEAKER_MUTE 0x19
#define WM_WRITE_SPEAKER_DATA 0x18
struct wm_speaker_data
{
@ -383,9 +383,12 @@ struct cc_trigger
struct nu_cal
{
wm_accel cal_zero; // zero calibration
u8 pad1;
wm_accel cal_g; // g size
u8 pad2;
nu_js jx; //
nu_js jy; //
u8 sum[2];
};
struct cc_cal