Wiimote cleanup, especially for Roll & Pitch, now accelerometer axes should be correct.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4654 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-12-06 18:26:20 +00:00
parent ec983284c6
commit 0238727c52
7 changed files with 151 additions and 155 deletions

View File

@ -153,10 +153,6 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_UseRealWiimote[i]->SetToolTip(wxT("Use the real Wiimote in the game. This can be changed during gameplay. This can not be selected") m_UseRealWiimote[i]->SetToolTip(wxT("Use the real Wiimote in the game. This can be changed during gameplay. This can not be selected")
wxT(" when a recording is to be done. No status in this window will be updated when this is checked.")); wxT(" when a recording is to be done. No status in this window will be updated when this is checked."));
m_SizeReal[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Real Wiimote"));
m_SizeReal[i]->Add(m_ConnectRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_SizeReal[i]->Add(m_UseRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_WiiMotionPlusConnected[i] = new wxCheckBox(m_Controller[i], ID_MOTIONPLUSCONNECTED, wxT("Wii Motion Plus Connected")); m_WiiMotionPlusConnected[i] = new wxCheckBox(m_Controller[i], ID_MOTIONPLUSCONNECTED, wxT("Wii Motion Plus Connected"));
m_WiiMotionPlusConnected[i]->SetValue(g_Config.bMotionPlusConnected); m_WiiMotionPlusConnected[i]->SetValue(g_Config.bMotionPlusConnected);
m_WiiMotionPlusConnected[i]->Enable(false); m_WiiMotionPlusConnected[i]->Enable(false);
@ -173,29 +169,19 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
extensionChoice[i] = new wxChoice(m_Controller[i], ID_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator); extensionChoice[i] = new wxChoice(m_Controller[i], ID_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator);
extensionChoice[i]->SetSelection(0); extensionChoice[i]->SetSelection(0);
m_SizeExtensions[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Extension(s)"));
m_SizeExtensions[i]->Add(m_WiiMotionPlusConnected[i], 0, wxEXPAND | wxALL, 5);
m_SizeExtensions[i]->Add(extensionChoice[i], 0, wxEXPAND | wxALL, 5);
m_SizeBasicGeneralLeft[i] = new wxBoxSizer(wxVERTICAL);
m_SizeBasicGeneralLeft[i]->Add(m_SizeReal[i], 0, wxEXPAND | wxALL, 5);
m_SizeBasicGeneralLeft[i]->Add(m_SizeExtensions[i], 0, wxEXPAND | wxALL, 5);
// Basic Settings // Basic Settings
m_WiimoteOnline[i] = new wxCheckBox(m_Controller[i], IDC_WIMOTE_ON, wxT("Wiimote On")); m_WiimoteOnline[i] = new wxCheckBox(m_Controller[i], IDC_WIMOTE_ON, wxT("Wiimote On"));
m_WiimoteOnline[i]->SetValue(true); m_WiimoteOnline[i]->SetValue(true);
m_WiimoteOnline[i]->Enable(false); m_WiimoteOnline[i]->Enable(false);
m_WiimoteOnline[i]->SetToolTip(wxString::Format(wxT("Decide if Wiimote %i shall be detected by the game"), i)); m_WiimoteOnline[i]->SetToolTip(wxString::Format(wxT("Decide if Wiimote %i shall be detected by the game"), i));
m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("General Settings"));
m_SizeBasic[i]->Add(m_WiimoteOnline[i], 0, wxEXPAND | wxALL, 5);
// Emulated Wiimote // Emulated Wiimote
m_SidewaysDPad[i] = new wxCheckBox(m_Controller[i], ID_SIDEWAYSDPAD, wxT("Sideways D-Pad")); m_SidewaysDPad[i] = new wxCheckBox(m_Controller[i], ID_SIDEWAYSDPAD, wxT("Sideways Wiimote"));
m_SidewaysDPad[i]->SetValue(g_Config.bSidewaysDPad); m_SidewaysDPad[i]->SetValue(g_Config.bSidewaysDPad);
m_SidewaysDPad[i]->SetToolTip(wxT("Treat the sideways position as neutral"));
m_UprightWiimote[i] = new wxCheckBox(m_Controller[i], ID_UPRIGHTWIIMOTE, wxT("Upright Wiimote")); m_UprightWiimote[i] = new wxCheckBox(m_Controller[i], ID_UPRIGHTWIIMOTE, wxT("Upright Wiimote"));
m_UprightWiimote[i]->SetValue(g_Config.Trigger.Upright); m_UprightWiimote[i]->SetValue(g_Config.Trigger.Upright);
m_UprightWiimote[i]->SetToolTip(wxT("Treat the upright position as neutral for roll and pitch")); m_UprightWiimote[i]->SetToolTip(wxT("Treat the upright position as neutral"));
//IR Pointer //IR Pointer
m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000")); m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000"));
@ -208,17 +194,6 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_SliderLeft[i] = new wxSlider(m_Controller[i], IDS_LEFT, 0, 100, 500, wxDefaultPosition, wxSize(75, -1)); m_SliderLeft[i] = new wxSlider(m_Controller[i], IDS_LEFT, 0, 100, 500, wxDefaultPosition, wxSize(75, -1));
m_SliderTop[i] = new wxSlider(m_Controller[i], IDS_TOP, 0, 0, 500, wxDefaultPosition, wxSize(75, -1)); m_SliderTop[i] = new wxSlider(m_Controller[i], IDS_TOP, 0, 0, 500, wxDefaultPosition, wxSize(75, -1));
m_SizerIRPointerWidth[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerWidth[i]->Add(m_TextScreenLeft[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderLeft[i], 0, wxEXPAND | (wxRIGHT), 0);
m_SizerIRPointerWidth[i]->Add(m_TextScreenWidth[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderWidth[i], 0, wxEXPAND | (wxLEFT), 0);
m_SizerIRPointerHeight[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerHeight[i]->Add(m_TextScreenTop[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerHeight[i]->Add(m_SliderTop[i], 0, wxEXPAND | (wxRIGHT), 0);
m_SizerIRPointerHeight[i]->Add(m_TextScreenHeight[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerHeight[i]->Add(m_SliderHeight[i], 0, wxEXPAND | (wxLEFT), 0);
//m_ScreenSize = new wxCheckBox(m_Controller[i], IDC_SCREEN_SIZE, wxT("Adjust screen size and position"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); //m_ScreenSize = new wxCheckBox(m_Controller[i], IDC_SCREEN_SIZE, wxT("Adjust screen size and position"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
//m_ScreenSize[i]->SetToolTip(wxT("Use the adjusted screen size.")); //m_ScreenSize[i]->SetToolTip(wxT("Use the adjusted screen size."));
@ -232,32 +207,55 @@ void WiimoteBasicConfigDialog::CreateGUIControls()
m_CheckAR169[i]->SetValue(g_Config.bKeepAR169); m_CheckAR169[i]->SetValue(g_Config.bKeepAR169);
m_Crop[i]->SetValue(g_Config.bCrop); m_Crop[i]->SetValue(g_Config.bCrop);
m_TextAR[i]->Enable(false);
m_CheckAR43[i]->Enable(false); m_CheckAR43[i]->Enable(false);
m_CheckAR169[i]->Enable(false); m_CheckAR169[i]->Enable(false);
m_Crop[i]->Enable(false); m_Crop[i]->Enable(false);
// Sizers // Sizers
m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("General Settings"));
m_SizeBasic[i]->Add(m_WiimoteOnline[i], 0, wxEXPAND | wxALL, 5);
m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Wiimote")); m_SizeEmu[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Position"));
m_SizeEmu[i]->Add(m_SidewaysDPad[i], 0, wxEXPAND | wxALL, 5); m_SizeEmu[i]->Add(m_SidewaysDPad[i], 0, wxEXPAND | wxALL, 5);
m_SizeEmu[i]->Add(m_UprightWiimote[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5); m_SizeEmu[i]->Add(m_UprightWiimote[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5);
m_SizeExtensions[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated Extension"));
m_SizeExtensions[i]->Add(m_WiiMotionPlusConnected[i], 0, wxEXPAND | wxALL, 5);
m_SizeExtensions[i]->Add(extensionChoice[i], 0, wxEXPAND | wxALL, 5);
m_SizeReal[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Real Wiimote"));
m_SizeReal[i]->Add(m_ConnectRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_SizeReal[i]->Add(m_UseRealWiimote[i], 0, wxEXPAND | wxALL, 5);
m_SizerIRPointerWidth[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerWidth[i]->Add(m_TextScreenLeft[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderLeft[i], 0, wxEXPAND | (wxRIGHT), 0);
m_SizerIRPointerWidth[i]->Add(m_TextScreenWidth[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerWidth[i]->Add(m_SliderWidth[i], 0, wxEXPAND | (wxLEFT), 0);
m_SizerIRPointerHeight[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerHeight[i]->Add(m_TextScreenTop[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerHeight[i]->Add(m_SliderTop[i], 0, wxEXPAND | (wxRIGHT), 0);
m_SizerIRPointerHeight[i]->Add(m_TextScreenHeight[i], 0, wxEXPAND | (wxTOP), 3);
m_SizerIRPointerHeight[i]->Add(m_SliderHeight[i], 0, wxEXPAND | (wxLEFT), 0);
m_SizerIRPointerScreen[i] = new wxBoxSizer(wxHORIZONTAL); m_SizerIRPointerScreen[i] = new wxBoxSizer(wxHORIZONTAL);
m_SizerIRPointerScreen[i]->Add(m_TextAR[i], 0, wxEXPAND | (wxTOP), 0); m_SizerIRPointerScreen[i]->Add(m_TextAR[i], 0, wxEXPAND | (wxTOP), 0);
m_SizerIRPointerScreen[i]->Add(m_CheckAR43[i], 0, wxEXPAND | (wxLEFT), 5); m_SizerIRPointerScreen[i]->Add(m_CheckAR43[i], 0, wxEXPAND | (wxLEFT), 5);
m_SizerIRPointerScreen[i]->Add(m_CheckAR169[i], 0, wxEXPAND | (wxLEFT), 5); m_SizerIRPointerScreen[i]->Add(m_CheckAR169[i], 0, wxEXPAND | (wxLEFT), 5);
m_SizerIRPointerScreen[i]->Add(m_Crop[i], 0, wxEXPAND | (wxLEFT), 5); m_SizerIRPointerScreen[i]->Add(m_Crop[i], 0, wxEXPAND | (wxLEFT), 5);
m_SizerIRPointer[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("IR pointer")); m_SizerIRPointer[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("IR Pointer"));
//m_SizerIRPointer[i]->Add(m_ScreenSize[i], 0, wxEXPAND | (wxALL), 5);
m_SizerIRPointer[i]->Add(m_SizerIRPointerWidth[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5); m_SizerIRPointer[i]->Add(m_SizerIRPointerWidth[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5);
m_SizerIRPointer[i]->Add(m_SizerIRPointerHeight[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5); m_SizerIRPointer[i]->Add(m_SizerIRPointerHeight[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5);
m_SizerIRPointer[i]->Add(m_SizerIRPointerScreen[i], 0, wxEXPAND | (wxLEFT | wxDOWN | wxRIGHT), 5); m_SizerIRPointer[i]->Add(m_SizerIRPointerScreen[i], 0, wxALIGN_CENTER | (wxUP | wxDOWN), 10);
m_SizeBasicGeneralLeft[i] = new wxBoxSizer(wxVERTICAL);
m_SizeBasicGeneralLeft[i]->Add(m_SizeBasic[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneralLeft[i]->Add(m_SizeEmu[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneralLeft[i]->Add(m_SizeExtensions[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneralRight[i] = new wxBoxSizer(wxVERTICAL); m_SizeBasicGeneralRight[i] = new wxBoxSizer(wxVERTICAL);
m_SizeBasicGeneralRight[i]->Add(m_SizeBasic[i], 0, wxEXPAND | (wxUP), 0); m_SizeBasicGeneralRight[i]->Add(m_SizeReal[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneralRight[i]->Add(m_SizeEmu[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneralRight[i]->Add(m_SizerIRPointer[i], 0, wxEXPAND | (wxUP), 5); m_SizeBasicGeneralRight[i]->Add(m_SizerIRPointer[i], 0, wxEXPAND | (wxUP), 5);
m_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL); m_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL);

View File

@ -487,8 +487,8 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
m_TiltComboInput[i] = new wxComboBox(m_Controller[i], ID_TILT_INPUT, StrTilt[0], wxDefaultPosition, wxSize(100, -1), StrTilt, wxCB_READONLY); m_TiltComboInput[i] = new wxComboBox(m_Controller[i], ID_TILT_INPUT, StrTilt[0], wxDefaultPosition, wxSize(100, -1), StrTilt, wxCB_READONLY);
m_TiltComboRangeRoll[i] = new wxComboBox(m_Controller[i], ID_TILT_RANGE_ROLL, StrTiltRangeRoll[0], wxDefaultPosition, wxSize(75, -1), StrTiltRangeRoll, wxCB_READONLY); m_TiltComboRangeRoll[i] = new wxComboBox(m_Controller[i], ID_TILT_RANGE_ROLL, StrTiltRangeRoll[0], wxDefaultPosition, wxSize(75, -1), StrTiltRangeRoll, wxCB_READONLY);
m_TiltComboRangePitch[i] = new wxComboBox(m_Controller[i], ID_TILT_RANGE_PITCH, StrTiltRangePitch[0], wxDefaultPosition, wxSize(75, -1), StrTiltRangePitch, wxCB_READONLY); m_TiltComboRangePitch[i] = new wxComboBox(m_Controller[i], ID_TILT_RANGE_PITCH, StrTiltRangePitch[0], wxDefaultPosition, wxSize(75, -1), StrTiltRangePitch, wxCB_READONLY);
m_TiltTextRoll[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Roll")); m_TiltTextRoll[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Roll L/R"));
m_TiltTextPitch[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Pitch")); m_TiltTextPitch[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Pitch U/D"));
m_TiltInvertRoll[i] = new wxCheckBox(m_Controller[i], ID_TILT_INVERT_ROLL, wxT("Invert")); m_TiltInvertRoll[i] = new wxCheckBox(m_Controller[i], ID_TILT_INVERT_ROLL, wxT("Invert"));
m_TiltInvertPitch[i] = new wxCheckBox(m_Controller[i], ID_TILT_INVERT_PITCH, wxT("Invert")); m_TiltInvertPitch[i] = new wxCheckBox(m_Controller[i], ID_TILT_INVERT_PITCH, wxT("Invert"));
@ -505,7 +505,7 @@ void WiimotePadConfigDialog::CreatePadGUIControls()
// For additional padding options if needed // For additional padding options if needed
//m_TiltHoriz[i] = new wxBoxSizer(wxHORIZONTAL); //m_TiltHoriz[i] = new wxBoxSizer(wxHORIZONTAL);
m_gTilt[i] = new wxStaticBoxSizer (wxVERTICAL, m_Controller[i], wxT("Roll and pitch")); m_gTilt[i] = new wxStaticBoxSizer (wxVERTICAL, m_Controller[i], wxT("Tilt and Swing"));
m_gTilt[i]->AddStretchSpacer(); m_gTilt[i]->AddStretchSpacer();
m_gTilt[i]->Add(m_TiltComboInput[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); m_gTilt[i]->Add(m_TiltComboInput[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_gTilt[i]->Add(m_TiltGrid[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5); m_gTilt[i]->Add(m_TiltGrid[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5);

View File

@ -89,30 +89,26 @@ void AdjustAngles(int &Roll, int &Pitch)
// Angles to accelerometer values // Angles to accelerometer values
void PitchDegreeToAccelerometer(int Roll, int Pitch, u8 &_x, u8 &_y, u8 &_z) void PitchDegreeToAccelerometer(int Roll, int Pitch, int &_x, int &_y, int &_z)
{ {
// Direct mapping from analog stick to x/y accelerometer // Direct mapping for swing, from analog stick to accelerometer
if (g_Config.Trigger.Range.Roll == 0 && g_Config.Trigger.Range.Pitch == 0) if (g_Config.Trigger.Range.Roll == 0 && g_Config.Trigger.Range.Pitch == 0)
{ {
// Make a deadzone to avoid trouble
if (abs(Roll) <= abs(g_wm.cal_g.x)) if (abs(Roll) <= abs(g_wm.cal_g.x))
Roll = 0; Roll = 0;
if (abs(Pitch) <= abs(g_wm.cal_g.z)) if (abs(Pitch) <= abs(g_wm.cal_g.z))
Pitch = 0; Pitch = 0;
int ix = g_wm.cal_zero.x + Roll;
int iz = g_wm.cal_zero.z + g_wm.cal_g.z + Pitch;
if (ix > 0xFF) ix = 0xFF;
if (ix < 0x00) ix = 0x00;
if (iz > 0xFF) iz = 0xFF;
if (iz < 0x00) iz = 0x00;
if (!g_Config.Trigger.Upright) if (!g_Config.Trigger.Upright)
{ {
_x = ix; _x -= Roll;
_z = iz; _z -= Pitch;
} }
else else // Upright wiimote
{ {
_x = ix; _x -= Roll;
_y = iz; _y += Pitch;
} }
return; return;
} }
@ -126,29 +122,13 @@ void PitchDegreeToAccelerometer(int Roll, int Pitch, u8 &_x, u8 &_y, u8 &_z)
// In these cases we can use the simple and accurate formula // In these cases we can use the simple and accurate formula
if(g_Config.Trigger.Range.Pitch == 0) if(g_Config.Trigger.Range.Pitch == 0)
{ {
if (!g_Config.Trigger.Upright) x = sin(_Roll);
{ z = cos(_Roll);
x = sin(_Roll);
z = cos(_Roll);
}
else
{
z = sin(_Roll);
y = -cos(_Roll);
}
} }
else if (g_Config.Trigger.Range.Roll == 0) else if (g_Config.Trigger.Range.Roll == 0)
{ {
if (!g_Config.Trigger.Upright) y = sin(_Pitch);
{ z = cos(_Pitch);
y = sin(_Pitch);
z = cos(_Pitch);
}
else
{
x = -sin(_Pitch);
y = -cos(_Pitch);
}
} }
else else
{ {
@ -159,56 +139,39 @@ void PitchDegreeToAccelerometer(int Roll, int Pitch, u8 &_x, u8 &_y, u8 &_z)
and Pitch. But if we select a Z from the smallest of the absolute and Pitch. But if we select a Z from the smallest of the absolute
value of cos(Roll) and cos (Pitch) we get the right values. */ value of cos(Roll) and cos (Pitch) we get the right values. */
// --------- // ---------
if (!g_Config.Trigger.Upright) if (abs(cos(_Roll)) < abs(cos(_Pitch)))
{ z = cos(_Roll);
if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
/* I got these from reversing the calculation in
PitchAccelerometerToDegree() in a math program. */
float x_num = 2 * tanf(0.5f * _Roll) * z;
float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
x = - (x_num / x_den);
float y_num = 2 * tanf(0.5f * _Pitch) * z;
float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
y = - (y_num / y_den);
}
else else
{ z = cos(_Pitch);
if (abs(-cos(_Roll)) < abs(-cos(_Pitch))) y = -cos(_Roll); else y = -cos(_Pitch); /* I got these from reversing the calculation in
float z_num = 2 * tanf(0.5f * _Roll) * y; PitchAccelerometerToDegree() in a math program. */
float z_den = pow2f(tanf(0.5f * _Roll)) - 1; float x_num = 2 * tanf(0.5f * _Roll) * z;
z = (z_num / z_den); float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
float x_num = 2 * tanf(0.5f * _Pitch) * y; x = - (x_num / x_den);
float x_den = pow2f(tanf(0.5f * _Pitch)) - 1; float y_num = 2 * tanf(0.5f * _Pitch) * z;
x = - (x_num / x_den); float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
} y = - (y_num / y_den);
} }
// Multiply with the neutral of z and its g // Multiply with neutral value and its g
float xg = g_wm.cal_g.x; float xg = g_wm.cal_g.x;
float yg = g_wm.cal_g.y; float yg = g_wm.cal_g.y;
float zg = g_wm.cal_g.z; float zg = g_wm.cal_g.z;
float x_zero = g_wm.cal_zero.x; int ix = g_wm.cal_zero.x + (int)(xg * x);
float y_zero = g_wm.cal_zero.y; int iy = g_wm.cal_zero.y + (int)(yg * y);
float z_zero = g_wm.cal_zero.z; int iz = g_wm.cal_zero.z + (int)(zg * z);
int ix = (int) (x_zero + xg * x);
int iy = (int) (y_zero + yg * y);
int iz = (int) (z_zero + zg * z);
// Boundaries
if (ix < 0) ix = 0; if (ix > 255) ix = 255;
if (iy < 0) iy = 0; if (iy > 255) iy = 255;
if (iz < 0) iz = 0; if (iz > 255) iz = 255;
if (!g_Config.Trigger.Upright) if (!g_Config.Trigger.Upright)
{ {
if(g_Config.Trigger.Range.Roll != 0) _x = ix; if(g_Config.Trigger.Range.Roll != 0) _x = ix;
if(g_Config.Trigger.Range.Pitch != 0) _y = iy; if(g_Config.Trigger.Range.Pitch != 0) _y = iy;
_z = iz; _z = iz;
} }
else else // Upright wiimote
{ {
if(g_Config.Trigger.Range.Roll != 0) _z = iz; if(g_Config.Trigger.Range.Roll != 0) _x = ix;
if(g_Config.Trigger.Range.Pitch != 0) _x = ix; if(g_Config.Trigger.Range.Pitch != 0) _z = iy;
_y = iy; _y = 0xFF - iz;
} }
} }

View File

@ -38,6 +38,9 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
extern void PAD_Rumble(u8 _numPAD, unsigned int _uType);
/* Bit shift conversions */ /* Bit shift conversions */
u32 convert24bit(const u8* src) { u32 convert24bit(const u8* src) {
return (src[0] << 16) | (src[1] << 8) | src[2]; return (src[0] << 16) | (src[1] << 8) | src[2];
@ -513,6 +516,7 @@ void Shutdown(void)
if (joyinfo.at(PadMapping[i].ID).Good) if (joyinfo.at(PadMapping[i].ID).Good)
{ {
INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy); INFO_LOG(WIIMOTE, "ShutDown: %i", PadState[i].joy);
PAD_Rumble(i, false);
/* SDL_JoystickClose() crashes for some reason so I avoid this /* SDL_JoystickClose() crashes for some reason so I avoid this
for now, SDL_Quit() should close the pads to I think */ for now, SDL_Quit() should close the pads to I think */
//if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy); //if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);

View File

@ -57,11 +57,10 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr); void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr);
// Accelerometer // Accelerometer
void PitchDegreeToAccelerometer(int _Roll, int _Pitch, u8 &_x, u8 &_y, u8 &_z); void PitchDegreeToAccelerometer(int _Roll, int _Pitch, int &_x, int &_y, int &_z);
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&); void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&);
float AccelerometerToG(float Current, float Neutral, float G); float AccelerometerToG(float Current, float Neutral, float G);
//void TiltTest(u8 x, u8 y, u8 z); void Tilt(int &_x, int &_y, int &_z);
void Tilt(u8 &_x, u8 &_y, u8 &_z);
void AdjustAngles(int &Roll, int &Pitch); void AdjustAngles(int &Roll, int &Pitch);
// IR data // IR data

View File

@ -129,7 +129,9 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
// Send general feedback except the following types // Send general feedback except the following types
// as these ones generate their own feedbacks // as these ones generate their own feedbacks
if ((sr->wm != WM_READ_DATA) // or don't send feedbacks
if ((sr->wm != WM_RUMBLE)
&& (sr->wm != WM_READ_DATA)
&& (sr->wm != WM_REQUEST_STATUS) && (sr->wm != WM_REQUEST_STATUS)
&& (sr->wm != WM_WRITE_SPEAKER_DATA) && (sr->wm != WM_WRITE_SPEAKER_DATA)
) )

View File

@ -414,16 +414,27 @@ void FillReportInfo(wm_core& _core)
source. The extremes are 0x00 for (-) and 0xff for (+). It's important that source. The extremes are 0x00 for (-) and 0xff for (+). It's important that
all values are not 0x80, the mouse pointer can disappear from the screen all values are not 0x80, the mouse pointer can disappear from the screen
permanently then, until z is adjusted back. This is because the game detects permanently then, until z is adjusted back. This is because the game detects
a steep pitch of the Wiimote then. */ a steep pitch of the Wiimote then.
Wiimote Accelerometer Axes
+ (- -- X -- +)
| ___
| | |\ -
| | + || \
| . || \
Y |. .|| Z
| . || \
| | . || \
| |___|| +
- ---
*/
// Global declarations for FillReportAcc: These variables are global so they // Global declarations for FillReportAcc: These variables are global so they
//can be changed during debugging int A = 0, B = 128, C = 64; // for debugging //can be changed during debugging int A = 0, B = 128, C = 64; // for debugging
//int a = 1, b = 1, c = 2, d = -2; // for debugging int consoleDisplay = 0; //int a = 1, b = 1, c = 2, d = -2; // for debugging int consoleDisplay = 0;
// For all functions
u8 g_x, g_y, g_z, g_X, g_Y, g_Z;
// For the shake function, Wiimote: wm = 0, Nunchuck: wm = 1 // For the shake function, Wiimote: wm = 0, Nunchuck: wm = 1
int Shake[] = {0, 0}; int Shake[] = {0, 0};
@ -431,9 +442,8 @@ int Shake[] = {0, 0};
std::vector<u8> yhist(15, 0); std::vector<u8> yhist(15, 0);
int KbDegree; int KbDegree;
// Single shake of all three directions // Single shake of all three directions
void SingleShake(u8 &_x, u8 &_y, u8 &_z, int wm) void SingleShake(int &_x, int &_y, int &_z, int wm)
{ {
#ifdef _WIN32 #ifdef _WIN32
if (Shake[wm] == 0) if (Shake[wm] == 0)
@ -472,9 +482,6 @@ void SingleShake(u8 &_x, u8 &_y, u8 &_z, int wm)
break; break;
default: default:
Shake[wm] = -1; Shake[wm] = -1;
_x = g_wm.cal_zero.x;
_y = g_wm.cal_zero.y;
_z = g_wm.cal_zero.z + g_wm.cal_g.z;
break; break;
} }
Shake[wm]++; Shake[wm]++;
@ -504,8 +511,8 @@ void TiltWiimoteGamepad(int &Roll, int &Pitch)
PadStateAdjustments(Lx, Ly, Rx, Ry, Tl, Tr); PadStateAdjustments(Lx, Ly, Rx, Ry, Tl, Tr);
// Save the Range in degrees, 45 and 90 are good values in some games // Save the Range in degrees, 45 and 90 are good values in some games
int RollRange = g_Config.Trigger.Range.Roll; int &RollRange = g_Config.Trigger.Range.Roll;
int PitchRange = g_Config.Trigger.Range.Pitch; int &PitchRange = g_Config.Trigger.Range.Pitch;
// The trigger currently only controls pitch // The trigger currently only controls pitch
if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER) if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER)
@ -516,8 +523,7 @@ void TiltWiimoteGamepad(int &Roll, int &Pitch)
// Invert // Invert
if (PadMapping[Page].bPitchInvert) { Tl = -Tl; Tr = -Tr; } if (PadMapping[Page].bPitchInvert) { Tl = -Tl; Tr = -Tr; }
// The final value // The final value
Pitch = Tl * ((float)PitchRange / 128.0) Pitch = PitchRange * ((float)(Tl - Tr) / 128.0);
- Tr * ((float)PitchRange / 128.0);
} }
/* For the analog stick roll is by default set to the X-axis, pitch is by /* For the analog stick roll is by default set to the X-axis, pitch is by
@ -526,8 +532,8 @@ void TiltWiimoteGamepad(int &Roll, int &Pitch)
else if (g_Config.Trigger.Type == g_Config.Trigger.ANALOG1) else if (g_Config.Trigger.Type == g_Config.Trigger.ANALOG1)
{ {
// Adjust the trigger to go between negative and positive values // Adjust the trigger to go between negative and positive values
Lx = Lx - 128; Lx = Lx - 0x80;
Ly = Ly - 128; Ly = Ly - 0x80;
// Invert // Invert
if (PadMapping[Page].bRollInvert) Lx = -Lx; // else Tr = -Tr; if (PadMapping[Page].bRollInvert) Lx = -Lx; // else Tr = -Tr;
if (PadMapping[Page].bPitchInvert) Ly = -Ly; // else Tr = -Tr; if (PadMapping[Page].bPitchInvert) Ly = -Ly; // else Tr = -Tr;
@ -539,8 +545,8 @@ void TiltWiimoteGamepad(int &Roll, int &Pitch)
else else
{ {
// Adjust the trigger to go between negative and positive values // Adjust the trigger to go between negative and positive values
Rx = Rx - 128; Rx = Rx - 0x80;
Ry = Ry - 128; Ry = Ry - 0x80;
// Invert // Invert
if (PadMapping[Page].bRollInvert) Rx = -Rx; // else Tr = -Tr; if (PadMapping[Page].bRollInvert) Rx = -Rx; // else Tr = -Tr;
if (PadMapping[Page].bPitchInvert) Ry = -Ry; // else Tr = -Tr; if (PadMapping[Page].bPitchInvert) Ry = -Ry; // else Tr = -Tr;
@ -559,10 +565,9 @@ void TiltWiimoteKeyboard(int &Roll, int &Pitch)
if (g_Config.Trigger.Range.Roll == 0 && g_Config.Trigger.Range.Pitch == 0) if (g_Config.Trigger.Range.Roll == 0 && g_Config.Trigger.Range.Pitch == 0)
{ {
if (IsKey(g_Wiimote_kbd.PITCH_L)) if (IsKey(g_Wiimote_kbd.PITCH_L))
Roll = -128 / 2; Roll = -0x80 / 2;
else if (IsKey(g_Wiimote_kbd.PITCH_R)) else if (IsKey(g_Wiimote_kbd.PITCH_R))
Roll = 128 / 2; Roll = 0x80 / 2;
return; return;
} }
@ -607,7 +612,7 @@ void TiltWiimoteKeyboard(int &Roll, int &Pitch)
} }
// Tilting Wiimote (Wario Land aiming, Mario Kart steering and other things) // Tilting Wiimote (Wario Land aiming, Mario Kart steering and other things)
void Tilt(u8 &_x, u8 &_y, u8 &_z) void Tilt(int &_x, int &_y, int &_z)
{ {
// Check if it's on // Check if it's on
if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER_OFF) return; if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER_OFF) return;
@ -626,10 +631,9 @@ void Tilt(u8 &_x, u8 &_y, u8 &_z)
AdjustAngles(Roll, Pitch); AdjustAngles(Roll, Pitch);
// Calculate the accelerometer value from this tilt angle // Calculate the accelerometer value from this tilt angle
//PitchDegreeToAccelerometer(Roll, Pitch, _x, _y, _z, g_Config.Trigger.Roll, g_Config.Trigger.Pitch);
PitchDegreeToAccelerometer(Roll, Pitch, _x, _y, _z); PitchDegreeToAccelerometer(Roll, Pitch, _x, _y, _z);
//DEBUG_LOG(WIIMOTE, "Roll:%i, Pitch:%i, _x:%i, _y:%i, _z:%i", Roll, Pitch, _x, _y, _z); //DEBUG_LOG(WIIMOTE, "Roll:%i, Pitch:%i, _x:%u, _y:%u, _z:%u", Roll, Pitch, _x, _y, _z);
} }
void FillReportAcc(wm_accel& _acc) void FillReportAcc(wm_accel& _acc)
@ -643,24 +647,42 @@ void FillReportAcc(wm_accel& _acc)
else else
{ {
// If the recording reached the end or failed somehow we will not return // If the recording reached the end or failed somehow we will not return
if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0)) return; if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0))
return;
//DEBUG_LOG(WIIMOTE, "X, Y, Z: %u %u %u", _acc.x, _acc.y, _acc.z); //DEBUG_LOG(WIIMOTE, "X, Y, Z: %u %u %u", _acc.x, _acc.y, _acc.z);
} }
// Initial value
int acc_x = g_wm.cal_zero.x;
int acc_y = g_wm.cal_zero.y;
int acc_z = g_wm.cal_zero.z;
if (!g_Config.Trigger.Upright)
acc_z += g_wm.cal_g.z;
else // Upright wiimote
acc_y -= g_wm.cal_g.y;
// Check that Dolphin is in focus // Check that Dolphin is in focus
if (!IsFocus()) if (IsFocus())
{ {
_acc.x = g_wm.cal_zero.x; // Shake the Wiimote
_acc.y = g_wm.cal_zero.y; SingleShake(acc_x, acc_y, acc_z, 0);
_acc.z = g_wm.cal_zero.z + g_wm.cal_g.z;
return; // Tilt Wiimote, allow the shake function to interrupt it
if (Shake[0] == 0) Tilt(acc_x, acc_y, acc_z);
// Boundary check
if (acc_x > 0xFF) acc_x = 0xFF;
else if (_acc.x < 0x00) acc_x = 0x00;
if (acc_y > 0xFF) acc_y = 0xFF;
else if (acc_y < 0x00) acc_y = 0x00;
if (acc_z > 0xFF) acc_z = 0xFF;
else if (acc_z < 0x00) acc_z = 0x00;
} }
// Shake the Wiimote _acc.x = acc_x;
SingleShake(_acc.x, _acc.y, _acc.z, 0); _acc.y = acc_y;
_acc.z = acc_z;
// Tilt Wiimote, allow the shake function to interrupt it
if (Shake[0] == 0) Tilt(_acc.x, _acc.y, _acc.z);
// Debugging for translating Wiimote to Keyboard (or Gamepad) // Debugging for translating Wiimote to Keyboard (or Gamepad)
/* /*
@ -723,7 +745,6 @@ void FillReportAcc(wm_accel& _acc)
else if(GetAsyncKeyState(VK_NUMPAD8)) else if(GetAsyncKeyState(VK_NUMPAD8))
Z-=1; Z-=1;
//if(consoleDisplay == 0) //if(consoleDisplay == 0)
DEBUG_LOG(WIIMOTE, "x: %03i | y: %03i | z: %03i | A:%i B:%i C:%i a:%i b:%i c:%i d:%i X:%i Y:%i Z:%i", DEBUG_LOG(WIIMOTE, "x: %03i | y: %03i | z: %03i | A:%i B:%i C:%i a:%i b:%i c:%i d:%i X:%i Y:%i Z:%i",
_acc.x, _acc.y, _acc.z, _acc.x, _acc.y, _acc.z,
@ -918,19 +939,28 @@ void FillReportExtension(wm_extension& _ext)
{ {
// Recorded movements // Recorded movements
// Check for a playback command // Check for a playback command
if(g_RecordingPlaying[1] < 0) g_RecordingPlaying[1] = RecordingCheckKeys(1); if(g_RecordingPlaying[1] < 0)
// We should not play back the accelerometer values
if (!(g_RecordingPlaying[1] >= 0 && RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1)))
{ {
// Use the neutral values g_RecordingPlaying[1] = RecordingCheckKeys(1);
_ext.ax = g_nu.cal_zero.x; }
_ext.ay = g_nu.cal_zero.y; else
_ext.az = g_nu.cal_zero.z + g_nu.cal_g.z; {
// We should not play back the accelerometer values
if (RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1))
return;
} }
// Use the neutral values
int ext_ax = g_nu.cal_zero.x;
int ext_ay = g_nu.cal_zero.y;
int ext_az = g_nu.cal_zero.z + g_nu.cal_g.z;
// Shake the Wiimote // Shake the Wiimote
SingleShake(_ext.ax, _ext.ay, _ext.az, 1); SingleShake(ext_ax, ext_ay, ext_az, 1);
_ext.ax = ext_ax;
_ext.ay = ext_ay;
_ext.az = ext_az;
// The default joystick and button values unless we use them // The default joystick and button values unless we use them
_ext.jx = g_nu.jx.center; _ext.jx = g_nu.jx.center;