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 // The id for a partially inserted extension
static const u8 partially_id[] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }; 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 // set up register
memcpy( &reg[0xfa], nothing_id, sizeof(nothing_id) ); memcpy(&id, nothing_id, sizeof(nothing_id));
} }
std::string Attachment::GetName() const std::string Attachment::GetName() const
@ -29,6 +31,14 @@ std::string Attachment::GetName() const
return name; 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 ) void ControllerEmu::Extension::GetState( u8* const data, const bool focus )

View File

@ -14,19 +14,23 @@ namespace WiimoteEmu
class Attachment : public ControllerEmu class Attachment : public ControllerEmu
{ {
public: public:
Attachment( const char* const _name ); Attachment( const char* const _name, WiimoteEmu::ExtensionReg& _reg );
virtual void GetState( u8* const data, const bool focus = true ) {} virtual void GetState( u8* const data, const bool focus = true ) {}
void Reset();
std::string GetName() const; std::string GetName() const;
const char* const name; const char* const name;
std::vector<u8> reg; WiimoteEmu::ExtensionReg& reg;
u8 id[6];
u8 calibration[0x10];
}; };
class None : public Attachment class None : public Attachment
{ {
public: 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::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 // buttons
groups.push_back(m_buttons = new Buttons("Buttons")); groups.push_back(m_buttons = new Buttons("Buttons"));
@ -76,9 +76,9 @@ Classic::Classic() : Attachment(_trans("Classic"))
// set up register // set up register
// calibration // calibration
memcpy(&reg[0x20], classic_calibration, sizeof(classic_calibration)); memcpy(&calibration, classic_calibration, sizeof(classic_calibration));
// id // 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) void Classic::GetState(u8* const data, const bool focus)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,8 @@ static const u8 nunchuk_button_bitmasks[] =
Nunchuk::BUTTON_Z, 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 // buttons
groups.push_back(m_buttons = new Buttons("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 // set up register
// calibration // calibration
memcpy(&reg[0x20], nunchuck_calibration, sizeof(nunchuck_calibration)); memcpy(&calibration, nunchuck_calibration, sizeof(nunchuck_calibration));
// id // 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 // this should get set to 0 on disconnect, but it isn't, o well
memset(m_shake_step, 0, sizeof(m_shake_step)); 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; wm_extension* const ncdata = (wm_extension*)data;
ncdata->bt = 0; ncdata->bt = 0;
// stick / not using calibration data for stick, o well // stick
m_stick->GetState(&ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0); 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; AccelData accel;
accel_cal* calib = (accel_cal*)&reg[0x20]; accel_cal* calib = (accel_cal*)&reg.calibration[0];
// tilt // tilt
EmulateTilt(&accel, m_tilt, focus); EmulateTilt(&accel, m_tilt, focus);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
#include <vector> #include <vector>
#include <queue> #include <queue>
// Registry sizes // Registry sizes
#define WIIMOTE_EEPROM_SIZE (16*1024) #define WIIMOTE_EEPROM_SIZE (16*1024)
#define WIIMOTE_EEPROM_FREE_SIZE 0x1700 #define WIIMOTE_EEPROM_FREE_SIZE 0x1700
#define WIIMOTE_REG_SPEAKER_SIZE 10 #define WIIMOTE_REG_SPEAKER_SIZE 10
@ -47,6 +47,30 @@ struct ADPCMState
s32 predictor, step; 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[]; extern const ReportFeatures reporting_mode_features[];
void EmulateShake(AccelData* const accel_data void EmulateShake(AccelData* const accel_data
@ -143,7 +167,7 @@ private:
ControlGroup* m_rumble; ControlGroup* m_rumble;
Extension* m_extension; Extension* m_extension;
ControlGroup* m_options; ControlGroup* m_options;
// WiiMote accel data // WiiMote accel data
AccelData m_accel; AccelData m_accel;
@ -151,7 +175,7 @@ private:
const u8 m_index; const u8 m_index;
double ir_sin, ir_cos; //for the low pass filter double ir_sin, ir_cos; //for the low pass filter
UDPWrapper* m_udp; UDPWrapper* m_udp;
bool m_rumble_on; bool m_rumble_on;
@ -201,30 +225,7 @@ private:
} m_reg_ir; } m_reg_ir;
struct ExtensionReg ExtensionReg m_reg_ext;
{
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;
struct SpeakerReg struct SpeakerReg
{ {

View File

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