Fix acceleration emulation for wiimote and nunchuk.
The 1-2 least significant bits were missing.
This commit is contained in:
parent
e9bbf00c88
commit
f07d3be502
|
@ -83,7 +83,7 @@ Classic::Classic(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Classic"),
|
||||||
void Classic::GetState(u8* const data)
|
void Classic::GetState(u8* const data)
|
||||||
{
|
{
|
||||||
wm_classic_extension* const ccdata = (wm_classic_extension*)data;
|
wm_classic_extension* const ccdata = (wm_classic_extension*)data;
|
||||||
ccdata->bt = 0;
|
ccdata->bt.hex = 0;
|
||||||
|
|
||||||
// not using calibration data, o well
|
// not using calibration data, o well
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ void Classic::GetState(u8* const data)
|
||||||
ControlState x, y;
|
ControlState x, y;
|
||||||
m_left_stick->GetState(&x, &y);
|
m_left_stick->GetState(&x, &y);
|
||||||
|
|
||||||
ccdata->lx = static_cast<u8>(Classic::LEFT_STICK_CENTER_X + (x * Classic::LEFT_STICK_RADIUS));
|
ccdata->regular_data.lx = static_cast<u8>(Classic::LEFT_STICK_CENTER_X + (x * Classic::LEFT_STICK_RADIUS));
|
||||||
ccdata->ly = static_cast<u8>(Classic::LEFT_STICK_CENTER_Y + (y * Classic::LEFT_STICK_RADIUS));
|
ccdata->regular_data.ly = static_cast<u8>(Classic::LEFT_STICK_CENTER_Y + (y * Classic::LEFT_STICK_RADIUS));
|
||||||
}
|
}
|
||||||
|
|
||||||
// right stick
|
// right stick
|
||||||
|
@ -115,7 +115,7 @@ void Classic::GetState(u8* const data)
|
||||||
{
|
{
|
||||||
ControlState trigs[2] = { 0, 0 };
|
ControlState trigs[2] = { 0, 0 };
|
||||||
u8 lt, rt;
|
u8 lt, rt;
|
||||||
m_triggers->GetState(&ccdata->bt, classic_trigger_bitmasks, trigs);
|
m_triggers->GetState(&ccdata->bt.hex, classic_trigger_bitmasks, trigs);
|
||||||
|
|
||||||
lt = static_cast<u8>(trigs[0] * Classic::LEFT_TRIGGER_RANGE);
|
lt = static_cast<u8>(trigs[0] * Classic::LEFT_TRIGGER_RANGE);
|
||||||
rt = static_cast<u8>(trigs[1] * Classic::RIGHT_TRIGGER_RANGE);
|
rt = static_cast<u8>(trigs[1] * Classic::RIGHT_TRIGGER_RANGE);
|
||||||
|
@ -126,12 +126,12 @@ void Classic::GetState(u8* const data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
m_buttons->GetState(&ccdata->bt, classic_button_bitmasks);
|
m_buttons->GetState(&ccdata->bt.hex, classic_button_bitmasks);
|
||||||
// dpad
|
// dpad
|
||||||
m_dpad->GetState(&ccdata->bt, classic_dpad_bitmasks);
|
m_dpad->GetState(&ccdata->bt.hex, classic_dpad_bitmasks);
|
||||||
|
|
||||||
// flip button bits
|
// flip button bits
|
||||||
ccdata->bt ^= 0xFFFF;
|
ccdata->bt.hex ^= 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,8 @@ Nunchuk::Nunchuk(WiimoteEmu::ExtensionReg& _reg) : Attachment(_trans("Nunchuk"),
|
||||||
|
|
||||||
void Nunchuk::GetState(u8* const data)
|
void Nunchuk::GetState(u8* const data)
|
||||||
{
|
{
|
||||||
wm_extension* const ncdata = (wm_extension*)data;
|
wm_nc* const ncdata = (wm_nc*)data;
|
||||||
ncdata->bt = 0;
|
ncdata->bt.hex = 0;
|
||||||
|
|
||||||
// stick
|
// stick
|
||||||
double state[2];
|
double state[2];
|
||||||
|
@ -107,12 +107,21 @@ void Nunchuk::GetState(u8* const data)
|
||||||
// shake
|
// shake
|
||||||
EmulateShake(&accel, m_shake, m_shake_step);
|
EmulateShake(&accel, m_shake, m_shake_step);
|
||||||
// buttons
|
// buttons
|
||||||
m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks);
|
m_buttons->GetState(&ncdata->bt.hex, nunchuk_button_bitmasks);
|
||||||
|
|
||||||
// flip the button bits :/
|
// flip the button bits :/
|
||||||
ncdata->bt ^= 0x03;
|
*(u8*)&ncdata->bt ^= 0x03;
|
||||||
|
|
||||||
FillRawAccelFromGForceData(*(wm_accel*)&ncdata->ax, *(accel_cal*)®.calibration, accel);
|
wm_full_accel tmpAccel;
|
||||||
|
|
||||||
|
FillRawAccelFromGForceData(tmpAccel, *(accel_cal*)®.calibration, accel);
|
||||||
|
|
||||||
|
ncdata->ax = tmpAccel.x >> 2;
|
||||||
|
ncdata->ay = tmpAccel.y >> 2;
|
||||||
|
ncdata->az = tmpAccel.z >> 2;
|
||||||
|
ncdata->passthrough_data.acc_x_lsb = tmpAccel.x & 0x3;
|
||||||
|
ncdata->passthrough_data.acc_y_lsb = tmpAccel.y & 0x3;
|
||||||
|
ncdata->passthrough_data.acc_z_lsb = tmpAccel.z & 0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nunchuk::LoadDefaults(const ControllerInterface& ciface)
|
void Nunchuk::LoadDefaults(const ControllerInterface& ciface)
|
||||||
|
|
|
@ -561,7 +561,7 @@ void Spy(Wiimote* wm_, const void* data_, size_t size_)
|
||||||
|
|
||||||
std::string SCore = "", SAcc = "", SIR = "", SExt = "", SExtID = "";
|
std::string SCore = "", SAcc = "", SIR = "", SExt = "", SExtID = "";
|
||||||
|
|
||||||
wm_core* core = (wm_core*)sr->data;
|
wm_buttons* core = (wm_buttons*)sr->data;
|
||||||
accel_cal* calib = (accel_cal*)&wm->m_eeprom[0x16];
|
accel_cal* calib = (accel_cal*)&wm->m_eeprom[0x16];
|
||||||
wm_accel* accel = (wm_accel*)&data[4];
|
wm_accel* accel = (wm_accel*)&data[4];
|
||||||
|
|
||||||
|
|
|
@ -79,13 +79,13 @@ static const ReportFeatures reporting_mode_features[] =
|
||||||
{ 0, 0, 0, 0, 23 },
|
{ 0, 0, 0, 0, 23 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void FillRawAccelFromGForceData(wm_accel& raw_accel,
|
void FillRawAccelFromGForceData(wm_full_accel& raw_accel,
|
||||||
const accel_cal& calib,
|
const accel_cal& calib,
|
||||||
const WiimoteEmu::AccelData& accel)
|
const WiimoteEmu::AccelData& accel)
|
||||||
{
|
{
|
||||||
raw_accel.x = (u8)trim(accel.x * (calib.one_g.x - calib.zero_g.x) + calib.zero_g.x);
|
raw_accel.x = (u16)trim(accel.x * (calib.one_g.x - calib.zero_g.x) + calib.zero_g.x);
|
||||||
raw_accel.y = (u8)trim(accel.y * (calib.one_g.y - calib.zero_g.y) + calib.zero_g.y);
|
raw_accel.y = (u16)trim(accel.y * (calib.one_g.y - calib.zero_g.y) + calib.zero_g.y);
|
||||||
raw_accel.z = (u8)trim(accel.z * (calib.one_g.z - calib.zero_g.z) + calib.zero_g.z);
|
raw_accel.z = (u16)trim(accel.z * (calib.one_g.z - calib.zero_g.z) + calib.zero_g.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulateShake(AccelData* const accel
|
void EmulateShake(AccelData* const accel
|
||||||
|
@ -376,13 +376,13 @@ bool Wiimote::Step()
|
||||||
void Wiimote::UpdateButtonsStatus()
|
void Wiimote::UpdateButtonsStatus()
|
||||||
{
|
{
|
||||||
// update buttons in status struct
|
// update buttons in status struct
|
||||||
m_status.buttons = 0;
|
m_status.buttons.hex = 0;
|
||||||
const bool is_sideways = m_options->settings[1]->value != 0;
|
const bool is_sideways = m_options->settings[1]->value != 0;
|
||||||
m_buttons->GetState(&m_status.buttons, button_bitmasks);
|
m_buttons->GetState(&m_status.buttons.hex, button_bitmasks);
|
||||||
m_dpad->GetState(&m_status.buttons, is_sideways ? dpad_sideways_bitmasks : dpad_bitmasks);
|
m_dpad->GetState(&m_status.buttons.hex, is_sideways ? dpad_sideways_bitmasks : dpad_bitmasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::GetCoreData(u8* const data)
|
void Wiimote::GetButtonData(u8* const data)
|
||||||
{
|
{
|
||||||
// when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues.
|
// when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues.
|
||||||
if (Core::g_want_determinism)
|
if (Core::g_want_determinism)
|
||||||
|
@ -390,10 +390,10 @@ void Wiimote::GetCoreData(u8* const data)
|
||||||
UpdateButtonsStatus();
|
UpdateButtonsStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
*(wm_core*)data |= m_status.buttons;
|
((wm_buttons*)data)->hex |= m_status.buttons.hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::GetAccelData(u8* const data)
|
void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf)
|
||||||
{
|
{
|
||||||
const bool is_sideways = m_options->settings[1]->value != 0;
|
const bool is_sideways = m_options->settings[1]->value != 0;
|
||||||
const bool is_upright = m_options->settings[2]->value != 0;
|
const bool is_upright = m_options->settings[2]->value != 0;
|
||||||
|
@ -406,7 +406,19 @@ void Wiimote::GetAccelData(u8* const data)
|
||||||
EmulateSwing(&m_accel, m_swing, is_sideways, is_upright);
|
EmulateSwing(&m_accel, m_swing, is_sideways, is_upright);
|
||||||
EmulateShake(&m_accel, m_shake, m_shake_step);
|
EmulateShake(&m_accel, m_shake, m_shake_step);
|
||||||
|
|
||||||
FillRawAccelFromGForceData(*(wm_accel*)data, *(accel_cal*)&m_eeprom[0x16], m_accel);
|
wm_full_accel tmpAccel;
|
||||||
|
|
||||||
|
FillRawAccelFromGForceData(tmpAccel, *(accel_cal*)&m_eeprom[0x16], m_accel);
|
||||||
|
|
||||||
|
wm_accel& accel = *(wm_accel*)(data + rptf.accel);
|
||||||
|
wm_buttons& core = *(wm_buttons*)(data + rptf.core);
|
||||||
|
|
||||||
|
accel.x = tmpAccel.x >> 2;
|
||||||
|
accel.y = tmpAccel.y >> 1;
|
||||||
|
accel.z = tmpAccel.z >> 1;
|
||||||
|
core.acc_x_lsb = tmpAccel.x & 0x3;
|
||||||
|
core.acc_y_lsb = tmpAccel.y & 0x1;
|
||||||
|
core.acc_z_lsb = tmpAccel.z & 0x1;
|
||||||
}
|
}
|
||||||
#define kCutoffFreq 5.0
|
#define kCutoffFreq 5.0
|
||||||
inline void LowPassFilter(double & var, double newval, double period)
|
inline void LowPassFilter(double & var, double newval, double period)
|
||||||
|
@ -566,7 +578,7 @@ void Wiimote::GetExtData(u8* const data)
|
||||||
|
|
||||||
// i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this.
|
// i dont think anything accesses the extension data like this, but ill support it. Indeed, commercial games don't do this.
|
||||||
// i think it should be unencrpyted in the register, encrypted when read.
|
// i think it should be unencrpyted in the register, encrypted when read.
|
||||||
memcpy(m_reg_ext.controller_data, data, sizeof(wm_extension));
|
memcpy(m_reg_ext.controller_data, data, sizeof(wm_nc)); // TODO: Should it be nc specific?
|
||||||
|
|
||||||
// motionplus pass-through modes
|
// motionplus pass-through modes
|
||||||
if (m_motion_plus_active)
|
if (m_motion_plus_active)
|
||||||
|
@ -606,7 +618,7 @@ void Wiimote::GetExtData(u8* const data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xAA == m_reg_ext.encryption)
|
if (0xAA == m_reg_ext.encryption)
|
||||||
WiimoteEncrypt(&m_ext_key, data, 0x00, sizeof(wm_extension));
|
WiimoteEncrypt(&m_ext_key, data, 0x00, sizeof(wm_nc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::Update()
|
void Wiimote::Update()
|
||||||
|
@ -629,7 +641,7 @@ void Wiimote::Update()
|
||||||
if (Movie::IsPlayingInput() && Movie::PlayWiimote(m_index, data, rptf, m_extension->active_extension, m_ext_key))
|
if (Movie::IsPlayingInput() && Movie::PlayWiimote(m_index, data, rptf, m_extension->active_extension, m_ext_key))
|
||||||
{
|
{
|
||||||
if (rptf.core)
|
if (rptf.core)
|
||||||
m_status.buttons = *(wm_core*)(data + rptf.core);
|
m_status.buttons = *(wm_buttons*)(data + rptf.core);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -638,11 +650,11 @@ void Wiimote::Update()
|
||||||
|
|
||||||
// core buttons
|
// core buttons
|
||||||
if (rptf.core)
|
if (rptf.core)
|
||||||
GetCoreData(data + rptf.core);
|
GetButtonData(data + rptf.core);
|
||||||
|
|
||||||
// acceleration
|
// acceleration
|
||||||
if (rptf.accel)
|
if (rptf.accel)
|
||||||
GetAccelData(data + rptf.accel);
|
GetAccelData(data, rptf);
|
||||||
|
|
||||||
// IR
|
// IR
|
||||||
if (rptf.ir)
|
if (rptf.ir)
|
||||||
|
@ -680,8 +692,8 @@ void Wiimote::Update()
|
||||||
// mix real-buttons with emu-buttons in the status struct, and in the report
|
// mix real-buttons with emu-buttons in the status struct, and in the report
|
||||||
if (real_rptf.core && rptf.core)
|
if (real_rptf.core && rptf.core)
|
||||||
{
|
{
|
||||||
m_status.buttons |= *(wm_core*)(real_data + real_rptf.core);
|
m_status.buttons.hex |= ((wm_buttons*)(real_data + real_rptf.core))->hex;
|
||||||
*(wm_core*)(data + rptf.core) = m_status.buttons;
|
*(wm_buttons*)(data + rptf.core) = m_status.buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
// accel
|
// accel
|
||||||
|
@ -695,7 +707,7 @@ void Wiimote::Update()
|
||||||
// ext
|
// ext
|
||||||
// use real-ext data if an emu-extention isn't chosen
|
// use real-ext data if an emu-extention isn't chosen
|
||||||
if (real_rptf.ext && rptf.ext && (0 == m_extension->switch_extension))
|
if (real_rptf.ext && rptf.ext && (0 == m_extension->switch_extension))
|
||||||
memcpy(data + rptf.ext, real_data + real_rptf.ext, sizeof(wm_extension));
|
memcpy(data + rptf.ext, real_data + real_rptf.ext, sizeof(wm_nc)); // TODO: Why NC specific?
|
||||||
}
|
}
|
||||||
else if (WM_ACK_DATA != real_data[1] || m_extension->active_extension > 0)
|
else if (WM_ACK_DATA != real_data[1] || m_extension->active_extension > 0)
|
||||||
rptf_size = 0;
|
rptf_size = 0;
|
||||||
|
@ -736,7 +748,7 @@ void Wiimote::Update()
|
||||||
{
|
{
|
||||||
NetPlay_GetWiimoteData(m_index, data, rptf.size);
|
NetPlay_GetWiimoteData(m_index, data, rptf.size);
|
||||||
if (rptf.core)
|
if (rptf.core)
|
||||||
m_status.buttons = *(wm_core*)(data + rptf.core);
|
m_status.buttons = *(wm_buttons*)(data + rptf.core);
|
||||||
}
|
}
|
||||||
if (!Movie::IsPlayingInput())
|
if (!Movie::IsPlayingInput())
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,7 @@ struct ExtensionReg
|
||||||
u8 constant_id[6];
|
u8 constant_id[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
void FillRawAccelFromGForceData(wm_accel& raw_accel,
|
void FillRawAccelFromGForceData(wm_full_accel& raw_accel,
|
||||||
const accel_cal& calib,
|
const accel_cal& calib,
|
||||||
const WiimoteEmu::AccelData& accel);
|
const WiimoteEmu::AccelData& accel);
|
||||||
|
|
||||||
|
@ -130,8 +130,8 @@ protected:
|
||||||
void HandleExtensionSwap();
|
void HandleExtensionSwap();
|
||||||
void UpdateButtonsStatus();
|
void UpdateButtonsStatus();
|
||||||
|
|
||||||
void GetCoreData(u8* const data);
|
void GetButtonData(u8* const data);
|
||||||
void GetAccelData(u8* const data);
|
void GetAccelData(u8* const data, const ReportFeatures& rptf);
|
||||||
void GetIRData(u8* const data, bool use_accel);
|
void GetIRData(u8* const data, bool use_accel);
|
||||||
void GetExtData(u8* const data);
|
void GetExtData(u8* const data);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4200)
|
#pragma warning(disable:4200)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
// Source: HID_010_SPC_PFL/1.0 (official HID specification)
|
// Source: HID_010_SPC_PFL/1.0 (official HID specification)
|
||||||
|
@ -30,15 +31,43 @@ struct hid_packet
|
||||||
#define HID_PARAM_INPUT 1
|
#define HID_PARAM_INPUT 1
|
||||||
#define HID_PARAM_OUTPUT 2
|
#define HID_PARAM_OUTPUT 2
|
||||||
|
|
||||||
//source: http://wiibrew.org/wiki/Wiimote
|
// Source: http://wiibrew.org/wiki/Wiimote
|
||||||
|
|
||||||
typedef u16 wm_core;
|
union wm_buttons // also just called "core data"
|
||||||
|
{
|
||||||
|
u16 hex;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 left : 1;
|
||||||
|
u8 right : 1;
|
||||||
|
u8 down : 1;
|
||||||
|
u8 up : 1;
|
||||||
|
u8 plus : 1;
|
||||||
|
u8 acc_x_lsb : 2; // LSB of accelerometer (10 bits in total)
|
||||||
|
u8 unknown : 1;
|
||||||
|
|
||||||
|
u8 two : 1;
|
||||||
|
u8 one : 1;
|
||||||
|
u8 b : 1;
|
||||||
|
u8 a : 1;
|
||||||
|
u8 minus : 1;
|
||||||
|
u8 acc_y_lsb : 1; // LSB of accelerometer (9 bits in total)
|
||||||
|
u8 acc_z_lsb : 1; // LSB of accelerometer (9 bits in total)
|
||||||
|
u8 home : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct wm_accel
|
struct wm_accel
|
||||||
{
|
{
|
||||||
u8 x, y, z;
|
u8 x, y, z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wm_full_accel
|
||||||
|
{
|
||||||
|
u16 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
// Four bytes for two objects. Filled with 0xFF if empty
|
// Four bytes for two objects. Filled with 0xFF if empty
|
||||||
struct wm_ir_basic
|
struct wm_ir_basic
|
||||||
{
|
{
|
||||||
|
@ -62,28 +91,152 @@ struct wm_ir_extended
|
||||||
u8 yhi : 2;
|
u8 yhi : 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_extension
|
// Nunchuk
|
||||||
|
union wm_nc_core
|
||||||
{
|
{
|
||||||
u8 jx; // joystick x, y
|
u8 hex;
|
||||||
u8 jy;
|
|
||||||
u8 ax; // accelerometer
|
struct
|
||||||
u8 ay;
|
{
|
||||||
u8 az;
|
u8 z : 1;
|
||||||
u8 bt; // buttons
|
u8 c : 1;
|
||||||
|
|
||||||
|
// LSBs of accelerometer
|
||||||
|
u8 acc_x_lsb : 2;
|
||||||
|
u8 acc_y_lsb : 2;
|
||||||
|
u8 acc_z_lsb : 2;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_classic_extension
|
union wm_nc
|
||||||
{
|
{
|
||||||
u8 lx : 6; // byte 0
|
struct
|
||||||
u8 rx3 : 2;
|
{
|
||||||
u8 ly : 6; // byte 1
|
// joystick x, y
|
||||||
u8 rx2 : 2;
|
u8 jx;
|
||||||
u8 ry : 5; // byte 2
|
u8 jy;
|
||||||
u8 lt2 : 2;
|
|
||||||
u8 rx1 : 1;
|
// accelerometer
|
||||||
u8 rt : 5; // byte 3
|
u8 ax;
|
||||||
u8 lt1 : 3;
|
u8 ay;
|
||||||
u16 bt; // byte 4, 5
|
u8 az;
|
||||||
|
|
||||||
|
wm_nc_core bt; // buttons + accelerometer LSBs
|
||||||
|
}; // regular data
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 reserved[4]; // jx, jy, ax and ay as in regular case
|
||||||
|
|
||||||
|
u8 extension_connected : 1;
|
||||||
|
u8 acc_z : 7; // MSBs of accelerometer data
|
||||||
|
|
||||||
|
u8 unknown : 1; // always 0?
|
||||||
|
u8 report_type : 1; // 1: report contains M+ data, 0: report contains extension data
|
||||||
|
|
||||||
|
u8 z : 1;
|
||||||
|
u8 c : 1;
|
||||||
|
|
||||||
|
// LSBs of accelerometer - starting from bit 1!
|
||||||
|
u8 acc_x_lsb : 1;
|
||||||
|
u8 acc_y_lsb : 1;
|
||||||
|
u8 acc_z_lsb : 2;
|
||||||
|
} passthrough_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
union wm_classic_extension_buttons
|
||||||
|
{
|
||||||
|
u16 hex;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 extension_connected : 1;
|
||||||
|
u8 rt : 1; // right trigger
|
||||||
|
u8 plus : 1;
|
||||||
|
u8 home : 1;
|
||||||
|
u8 minus : 1;
|
||||||
|
u8 lt : 1; // left trigger
|
||||||
|
u8 dpad_down : 1;
|
||||||
|
u8 dpad_right : 1;
|
||||||
|
|
||||||
|
u8 : 2; // cf. extension_data and passthrough_data
|
||||||
|
u8 zr : 1; // right z button
|
||||||
|
u8 x : 1;
|
||||||
|
u8 a : 1;
|
||||||
|
u8 y : 1;
|
||||||
|
u8 b : 1;
|
||||||
|
u8 zl : 1; // left z button
|
||||||
|
}; // common data
|
||||||
|
|
||||||
|
// M+ pass-through mode slightly differs from the regular data.
|
||||||
|
// Refer to the common data for unnamed fields
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 : 8;
|
||||||
|
|
||||||
|
u8 dpad_up : 1;
|
||||||
|
u8 dpad_left : 1;
|
||||||
|
u8 : 6;
|
||||||
|
} regular_data;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 : 8;
|
||||||
|
|
||||||
|
u8 unknown : 1; // always 0?
|
||||||
|
u8 report_type : 1; // 1: report contains M+ data, 0: report contains extension data
|
||||||
|
u8 : 6;
|
||||||
|
} passthrough_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
union wm_classic_extension
|
||||||
|
{
|
||||||
|
// lx/ly/lz; left joystick
|
||||||
|
// rx/ry/rz; right joystick
|
||||||
|
// lt; left trigger
|
||||||
|
// rt; left trigger
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 : 6;
|
||||||
|
u8 rx3 : 2;
|
||||||
|
|
||||||
|
u8 : 6;
|
||||||
|
u8 rx2 : 2;
|
||||||
|
|
||||||
|
u8 ry : 5;
|
||||||
|
u8 lt2 : 2;
|
||||||
|
u8 rx1 : 1;
|
||||||
|
|
||||||
|
u8 rt : 5;
|
||||||
|
u8 lt1 : 3;
|
||||||
|
|
||||||
|
wm_classic_extension_buttons bt; // byte 4, 5
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 lx : 6; // byte 0
|
||||||
|
u8 : 2;
|
||||||
|
|
||||||
|
u8 ly : 6; // byte 1
|
||||||
|
u8 : 2;
|
||||||
|
|
||||||
|
unsigned : 32;
|
||||||
|
} regular_data;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u8 dpad_up : 1;
|
||||||
|
u8 lx : 5; // Bits 1-5
|
||||||
|
u8 : 2;
|
||||||
|
|
||||||
|
u8 dpad_left : 1;
|
||||||
|
u8 ly : 5; // Bits 1-5
|
||||||
|
u8 : 2;
|
||||||
|
|
||||||
|
unsigned : 32;
|
||||||
|
} passthrough_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_guitar_extension
|
struct wm_guitar_extension
|
||||||
|
@ -148,23 +301,24 @@ struct wm_turntable_extension
|
||||||
|
|
||||||
struct wm_motionplus_data
|
struct wm_motionplus_data
|
||||||
{
|
{
|
||||||
|
// yaw1, roll1, pitch1: Bits 0-7
|
||||||
|
// yaw2, roll2, pitch2: Bits 8-13
|
||||||
|
|
||||||
u8 yaw1;
|
u8 yaw1;
|
||||||
|
|
||||||
u8 roll1;
|
u8 roll1;
|
||||||
|
|
||||||
u8 pitch1;
|
u8 pitch1;
|
||||||
|
|
||||||
u8 yaw2 : 6;
|
|
||||||
u8 yaw_slow : 1;
|
|
||||||
u8 pitch_slow : 1;
|
u8 pitch_slow : 1;
|
||||||
|
u8 yaw_slow : 1;
|
||||||
|
u8 yaw2 : 6;
|
||||||
|
|
||||||
u8 roll2 : 6;
|
|
||||||
u8 roll_slow : 1;
|
|
||||||
u8 extension_connected : 1;
|
u8 extension_connected : 1;
|
||||||
|
u8 roll_slow : 1;
|
||||||
|
u8 roll2 : 6;
|
||||||
|
|
||||||
u8 pitch2 : 6;
|
|
||||||
u8 is_mp_data : 1;
|
|
||||||
u8 zero : 1;
|
u8 zero : 1;
|
||||||
|
u8 is_mp_data : 1;
|
||||||
|
u8 pitch2 : 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_report
|
struct wm_report
|
||||||
|
@ -218,7 +372,7 @@ struct wm_request_status
|
||||||
#define WM_STATUS_REPORT 0x20
|
#define WM_STATUS_REPORT 0x20
|
||||||
struct wm_status_report
|
struct wm_status_report
|
||||||
{
|
{
|
||||||
wm_core buttons;
|
wm_buttons buttons;
|
||||||
u8 battery_low : 1;
|
u8 battery_low : 1;
|
||||||
u8 extension : 1;
|
u8 extension : 1;
|
||||||
u8 speaker : 1;
|
u8 speaker : 1;
|
||||||
|
@ -242,7 +396,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_buttons buttons;
|
||||||
u8 reportID;
|
u8 reportID;
|
||||||
u8 errorID;
|
u8 errorID;
|
||||||
};
|
};
|
||||||
|
@ -265,7 +419,7 @@ struct wm_read_data
|
||||||
#define WM_READ_DATA_REPLY 0x21
|
#define WM_READ_DATA_REPLY 0x21
|
||||||
struct wm_read_data_reply
|
struct wm_read_data_reply
|
||||||
{
|
{
|
||||||
wm_core buttons;
|
wm_buttons buttons;
|
||||||
u8 error : 4; //see WM_RDERR_*
|
u8 error : 4; //see WM_RDERR_*
|
||||||
u8 size : 4;
|
u8 size : 4;
|
||||||
u16 address;
|
u16 address;
|
||||||
|
@ -281,13 +435,13 @@ struct wm_read_data_reply
|
||||||
#define WM_REPORT_CORE 0x30
|
#define WM_REPORT_CORE 0x30
|
||||||
struct wm_report_core
|
struct wm_report_core
|
||||||
{
|
{
|
||||||
wm_core c;
|
wm_buttons c;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WM_REPORT_CORE_ACCEL 0x31
|
#define WM_REPORT_CORE_ACCEL 0x31
|
||||||
struct wm_report_core_accel
|
struct wm_report_core_accel
|
||||||
{
|
{
|
||||||
wm_core c;
|
wm_buttons c;
|
||||||
wm_accel a;
|
wm_accel a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -296,7 +450,7 @@ struct wm_report_core_accel
|
||||||
#define WM_REPORT_CORE_ACCEL_IR12 0x33
|
#define WM_REPORT_CORE_ACCEL_IR12 0x33
|
||||||
struct wm_report_core_accel_ir12
|
struct wm_report_core_accel_ir12
|
||||||
{
|
{
|
||||||
wm_core c;
|
wm_buttons c;
|
||||||
wm_accel a;
|
wm_accel a;
|
||||||
wm_ir_extended ir[4];
|
wm_ir_extended ir[4];
|
||||||
};
|
};
|
||||||
|
@ -305,9 +459,9 @@ struct wm_report_core_accel_ir12
|
||||||
#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_buttons c;
|
||||||
wm_accel a;
|
wm_accel a;
|
||||||
wm_extension ext;
|
wm_nc ext; // TODO: Does this make any sense? Shouldn't it be just a general "extension" field?
|
||||||
//wm_ir_basic ir[2];
|
//wm_ir_basic ir[2];
|
||||||
u8 pad[10];
|
u8 pad[10];
|
||||||
|
|
||||||
|
@ -318,11 +472,11 @@ struct wm_report_core_accel_ext16
|
||||||
#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_buttons c;
|
||||||
wm_accel a;
|
wm_accel a;
|
||||||
wm_ir_basic ir[2];
|
wm_ir_basic ir[2];
|
||||||
//u8 ext[6];
|
//u8 ext[6];
|
||||||
wm_extension ext;
|
wm_nc ext; // TODO: Does this make any sense? Shouldn't it be just a general "extension" field?
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WM_REPORT_EXT21 0x3d // never used?
|
#define WM_REPORT_EXT21 0x3d // never used?
|
||||||
|
|
|
@ -597,28 +597,28 @@ static void SetWiiInputDisplayString(int remoteID, u8* const data, const Wiimote
|
||||||
|
|
||||||
if (coreData)
|
if (coreData)
|
||||||
{
|
{
|
||||||
wm_core buttons = *(wm_core*)coreData;
|
wm_buttons buttons = *(wm_buttons*)coreData;
|
||||||
if (buttons & WiimoteEmu::Wiimote::PAD_LEFT)
|
if(buttons.left)
|
||||||
s_InputDisplay[controllerID].append(" LEFT");
|
s_InputDisplay[controllerID].append(" LEFT");
|
||||||
if (buttons & WiimoteEmu::Wiimote::PAD_RIGHT)
|
if(buttons.right)
|
||||||
s_InputDisplay[controllerID].append(" RIGHT");
|
s_InputDisplay[controllerID].append(" RIGHT");
|
||||||
if (buttons & WiimoteEmu::Wiimote::PAD_DOWN)
|
if(buttons.down)
|
||||||
s_InputDisplay[controllerID].append(" DOWN");
|
s_InputDisplay[controllerID].append(" DOWN");
|
||||||
if (buttons & WiimoteEmu::Wiimote::PAD_UP)
|
if(buttons.up)
|
||||||
s_InputDisplay[controllerID].append(" UP");
|
s_InputDisplay[controllerID].append(" UP");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_A)
|
if(buttons.a)
|
||||||
s_InputDisplay[controllerID].append(" A");
|
s_InputDisplay[controllerID].append(" A");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_B)
|
if(buttons.b)
|
||||||
s_InputDisplay[controllerID].append(" B");
|
s_InputDisplay[controllerID].append(" B");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_PLUS)
|
if(buttons.plus)
|
||||||
s_InputDisplay[controllerID].append(" +");
|
s_InputDisplay[controllerID].append(" +");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_MINUS)
|
if(buttons.minus)
|
||||||
s_InputDisplay[controllerID].append(" -");
|
s_InputDisplay[controllerID].append(" -");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_ONE)
|
if(buttons.one)
|
||||||
s_InputDisplay[controllerID].append(" 1");
|
s_InputDisplay[controllerID].append(" 1");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_TWO)
|
if(buttons.two)
|
||||||
s_InputDisplay[controllerID].append(" 2");
|
s_InputDisplay[controllerID].append(" 2");
|
||||||
if (buttons & WiimoteEmu::Wiimote::BUTTON_HOME)
|
if(buttons.home)
|
||||||
s_InputDisplay[controllerID].append(" HOME");
|
s_InputDisplay[controllerID].append(" HOME");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,16 +640,16 @@ static void SetWiiInputDisplayString(int remoteID, u8* const data, const Wiimote
|
||||||
// Nunchuck
|
// Nunchuck
|
||||||
if (extData && ext == 1)
|
if (extData && ext == 1)
|
||||||
{
|
{
|
||||||
wm_extension nunchuck;
|
wm_nc nunchuck;
|
||||||
memcpy(&nunchuck, extData, sizeof(wm_extension));
|
memcpy(&nunchuck, extData, sizeof(wm_nc));
|
||||||
WiimoteDecrypt(&key, (u8*)&nunchuck, 0, sizeof(wm_extension));
|
WiimoteDecrypt(&key, (u8*)&nunchuck, 0, sizeof(wm_nc));
|
||||||
nunchuck.bt = nunchuck.bt ^ 0xFF;
|
nunchuck.bt.hex = nunchuck.bt.hex ^ 0xFF;
|
||||||
|
|
||||||
std::string accel = StringFromFormat(" N-ACC:%d,%d,%d", nunchuck.ax, nunchuck.ay, nunchuck.az);
|
std::string accel = StringFromFormat(" N-ACC:%d,%d,%d", nunchuck.ax, nunchuck.ay, nunchuck.az);
|
||||||
|
|
||||||
if (nunchuck.bt & WiimoteEmu::Nunchuk::BUTTON_C)
|
if (nunchuck.bt.c)
|
||||||
s_InputDisplay[controllerID].append(" C");
|
s_InputDisplay[controllerID].append(" C");
|
||||||
if (nunchuck.bt & WiimoteEmu::Nunchuk::BUTTON_Z)
|
if (nunchuck.bt.z)
|
||||||
s_InputDisplay[controllerID].append(" Z");
|
s_InputDisplay[controllerID].append(" Z");
|
||||||
s_InputDisplay[controllerID].append(accel);
|
s_InputDisplay[controllerID].append(accel);
|
||||||
s_InputDisplay[controllerID].append(Analog2DToString(nunchuck.jx, nunchuck.jy, " ANA"));
|
s_InputDisplay[controllerID].append(Analog2DToString(nunchuck.jx, nunchuck.jy, " ANA"));
|
||||||
|
@ -661,38 +661,38 @@ static void SetWiiInputDisplayString(int remoteID, u8* const data, const Wiimote
|
||||||
wm_classic_extension cc;
|
wm_classic_extension cc;
|
||||||
memcpy(&cc, extData, sizeof(wm_classic_extension));
|
memcpy(&cc, extData, sizeof(wm_classic_extension));
|
||||||
WiimoteDecrypt(&key, (u8*)&cc, 0, sizeof(wm_classic_extension));
|
WiimoteDecrypt(&key, (u8*)&cc, 0, sizeof(wm_classic_extension));
|
||||||
cc.bt = cc.bt ^ 0xFFFF;
|
cc.bt.hex = cc.bt.hex ^ 0xFFFF;
|
||||||
|
|
||||||
if (cc.bt & WiimoteEmu::Classic::PAD_LEFT)
|
if (cc.bt.regular_data.dpad_left)
|
||||||
s_InputDisplay[controllerID].append(" LEFT");
|
s_InputDisplay[controllerID].append(" LEFT");
|
||||||
if (cc.bt & WiimoteEmu::Classic::PAD_RIGHT)
|
if (cc.bt.dpad_right)
|
||||||
s_InputDisplay[controllerID].append(" RIGHT");
|
s_InputDisplay[controllerID].append(" RIGHT");
|
||||||
if (cc.bt & WiimoteEmu::Classic::PAD_DOWN)
|
if (cc.bt.dpad_down)
|
||||||
s_InputDisplay[controllerID].append(" DOWN");
|
s_InputDisplay[controllerID].append(" DOWN");
|
||||||
if (cc.bt & WiimoteEmu::Classic::PAD_UP)
|
if (cc.bt.regular_data.dpad_up)
|
||||||
s_InputDisplay[controllerID].append(" UP");
|
s_InputDisplay[controllerID].append(" UP");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_A)
|
if (cc.bt.a)
|
||||||
s_InputDisplay[controllerID].append(" A");
|
s_InputDisplay[controllerID].append(" A");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_B)
|
if (cc.bt.b)
|
||||||
s_InputDisplay[controllerID].append(" B");
|
s_InputDisplay[controllerID].append(" B");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_X)
|
if (cc.bt.x)
|
||||||
s_InputDisplay[controllerID].append(" X");
|
s_InputDisplay[controllerID].append(" X");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_Y)
|
if (cc.bt.y)
|
||||||
s_InputDisplay[controllerID].append(" Y");
|
s_InputDisplay[controllerID].append(" Y");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_ZL)
|
if (cc.bt.zl)
|
||||||
s_InputDisplay[controllerID].append(" ZL");
|
s_InputDisplay[controllerID].append(" ZL");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_ZR)
|
if (cc.bt.zr)
|
||||||
s_InputDisplay[controllerID].append(" ZR");
|
s_InputDisplay[controllerID].append(" ZR");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_PLUS)
|
if (cc.bt.plus)
|
||||||
s_InputDisplay[controllerID].append(" +");
|
s_InputDisplay[controllerID].append(" +");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_MINUS)
|
if (cc.bt.minus)
|
||||||
s_InputDisplay[controllerID].append(" -");
|
s_InputDisplay[controllerID].append(" -");
|
||||||
if (cc.bt & WiimoteEmu::Classic::BUTTON_HOME)
|
if (cc.bt.home)
|
||||||
s_InputDisplay[controllerID].append(" HOME");
|
s_InputDisplay[controllerID].append(" HOME");
|
||||||
|
|
||||||
s_InputDisplay[controllerID].append(Analog1DToString(cc.lt1 | (cc.lt2 << 3), " L", 31));
|
s_InputDisplay[controllerID].append(Analog1DToString(cc.lt1 | (cc.lt2 << 3), " L", 31));
|
||||||
s_InputDisplay[controllerID].append(Analog1DToString(cc.rt, " R", 31));
|
s_InputDisplay[controllerID].append(Analog1DToString(cc.rt, " R", 31));
|
||||||
s_InputDisplay[controllerID].append(Analog2DToString(cc.lx, cc.ly, " ANA", 63));
|
s_InputDisplay[controllerID].append(Analog2DToString(cc.regular_data.lx, cc.regular_data.ly, " ANA", 63));
|
||||||
s_InputDisplay[controllerID].append(Analog2DToString(cc.rx1 | (cc.rx2 << 1) | (cc.rx3 << 3), cc.ry, " R-ANA", 31));
|
s_InputDisplay[controllerID].append(Analog2DToString(cc.rx1 | (cc.rx2 << 1) | (cc.rx3 << 3), cc.ry, " R-ANA", 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -378,7 +378,7 @@ void TASInputDlg::SetButtonValue(Button* button, bool CurrentState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TASInputDlg::SetWiiButtons(wm_core* butt)
|
void TASInputDlg::SetWiiButtons(u16* butt)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < 14; ++i)
|
for (unsigned int i = 0; i < 14; ++i)
|
||||||
{
|
{
|
||||||
|
@ -415,7 +415,7 @@ void TASInputDlg::GetKeyBoardInput(u8* data, WiimoteEmu::ReportFeatures rptf)
|
||||||
for (unsigned int i = 0; i < 14; ++i)
|
for (unsigned int i = 0; i < 14; ++i)
|
||||||
{
|
{
|
||||||
if (m_buttons[i] != nullptr)
|
if (m_buttons[i] != nullptr)
|
||||||
SetButtonValue(m_buttons[i], (*(wm_core*)coreData & m_wii_buttons_bitmask[i]) != 0);
|
SetButtonValue(m_buttons[i], (((wm_buttons*)coreData)->hex & m_wii_buttons_bitmask[i]) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (accelData)
|
if (accelData)
|
||||||
|
@ -450,7 +450,7 @@ void TASInputDlg::GetValues(u8* data, WiimoteEmu::ReportFeatures rptf)
|
||||||
u8* const irData = rptf.ir ? (data + rptf.ir) : nullptr;
|
u8* const irData = rptf.ir ? (data + rptf.ir) : nullptr;
|
||||||
|
|
||||||
if (coreData)
|
if (coreData)
|
||||||
SetWiiButtons((wm_core*)coreData);
|
SetWiiButtons(&((wm_buttons*)coreData)->hex);
|
||||||
|
|
||||||
if (accelData)
|
if (accelData)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ class TASInputDlg : public wxDialog
|
||||||
void CreateGCLayout();
|
void CreateGCLayout();
|
||||||
void CreateWiiLayout();
|
void CreateWiiLayout();
|
||||||
wxBitmap CreateStickBitmap(int x, int y);
|
wxBitmap CreateStickBitmap(int x, int y);
|
||||||
void SetWiiButtons(wm_core* butt);
|
void SetWiiButtons(u16* butt);
|
||||||
void GetIRData(u8* const data, u8 mode, bool use_accel);
|
void GetIRData(u8* const data, u8 mode, bool use_accel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue