Emulated Wiimote: Added option to use analog controls for the Nunchuck stick

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2243 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2009-02-15 02:01:43 +00:00
parent ae9bb905bf
commit 34dbb40ef5
11 changed files with 303 additions and 120 deletions

View File

@ -61,9 +61,10 @@ void Config::Load(bool ChangePad)
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
std::string SectionName = StringFromFormat("Wiimote%i", i + 1);
iniFile.Get(SectionName.c_str(), "NoTriggerFilter", &bNoTriggerFilter, false);
iniFile.Get(SectionName.c_str(), "TriggerType", &Trigger.Type, TRIGGER_OFF);
iniFile.Get(SectionName.c_str(), "TriggerType", &Trigger.Type, Trigger.TRIGGER_OFF);
iniFile.Get(SectionName.c_str(), "TriggerRollRange", &Trigger.Range.Roll, 50);
iniFile.Get(SectionName.c_str(), "TriggerPitchRange", &Trigger.Range.Pitch, false);
iniFile.Get(SectionName.c_str(), "NunchuckStick", &Nunchuck.Type, Nunchuck.KEYBOARD);
// Don't update this when we are loading settings from the ConfigBox
if(!ChangePad)
@ -138,6 +139,7 @@ void Config::Save(int Slot)
iniFile.Set(SectionName.c_str(), "TriggerType", Trigger.Type);
iniFile.Set(SectionName.c_str(), "TriggerRollRange", Trigger.Range.Roll);
iniFile.Set(SectionName.c_str(), "TriggerPitchRange", Trigger.Range.Pitch);
iniFile.Set(SectionName.c_str(), "NunchuckStick", Nunchuck.Type);
// Save the physical device ID number
iniFile.Set(SectionName.c_str(), "DeviceID", WiiMoteEmu::PadMapping[i].ID);

View File

@ -18,6 +18,7 @@
#ifndef _CONFIG_H
#define _CONFIG_H
struct Config
{
Config();
@ -32,17 +33,26 @@ struct Config
struct PadTrigger
{
enum ETriggerType
{
TRIGGER_OFF = 0,
KEYBOARD,
ANALOG1,
ANALOG2,
TRIGGER
};
int Type;
PadRange Range;
};
enum ETriggerType
struct PadNunchuck
{
TRIGGER_OFF = 0,
KEYBOARD,
ANALOG1,
ANALOG2,
TRIGGER
enum ENunchuckStick
{
KEYBOARD,
ANALOG1,
ANALOG2
};
int Type;
};
// Emulated Wiimote
@ -58,6 +68,7 @@ struct Config
// Gamepad
bool bNoTriggerFilter;
PadTrigger Trigger;
PadNunchuck Nunchuck;
};
extern Config g_Config;

View File

@ -111,7 +111,8 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CHECKBOX(IDC_LEFT_C2S, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_TILT_INVERT_ROLL, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_TILT_INVERT_PITCH, ConfigDialog::GeneralSettingsChanged)
EVT_COMBOBOX(IDCB_NUNCHUCK_STICK, ConfigDialog::GeneralSettingsChanged)
EVT_BUTTON(IDB_ANALOG_LEFT_X, ConfigDialog::GetButtons)
EVT_BUTTON(IDB_ANALOG_LEFT_Y, ConfigDialog::GetButtons)
EVT_BUTTON(IDB_ANALOG_RIGHT_X, ConfigDialog::GetButtons)
@ -162,8 +163,6 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl
LoadFile();
// Set control values
UpdateGUI();
// Update dead zone
DoChangeDeadZone(true); DoChangeDeadZone(false);
wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, // Keyboard
wxKeyEventHandler(ConfigDialog::OnKeyDown),
@ -436,6 +435,12 @@ void ConfigDialog::CreateGUIControls()
wxArrayString StrTriggerType;
StrTriggerType.Add(wxString::FromAscii("SDL")); // -0x8000 to 0x7fff
StrTriggerType.Add(wxString::FromAscii("XInput")); // 0x00 to 0xff
// The Nunchuck stick list
wxArrayString StrNunchuck;
StrNunchuck.Add(wxString::FromAscii("Keyboard"));
StrNunchuck.Add(wxString::FromAscii("Analog 1"));
StrNunchuck.Add(wxString::FromAscii("Analog 2"));
///////////////////////////////////////
@ -828,6 +833,8 @@ void ConfigDialog::CreateGUIControls()
// --------------------------------------------------------------------
// Wiimote
// -----------------------------
m_gWiimote[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Wiimote"));
/*
m_WmA[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
m_WmB[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
@ -875,12 +882,17 @@ void ConfigDialog::CreateGUIControls()
m_WmR[i]->Enable(false);
m_WmU[i]->Enable(false);
m_WmD[i]->Enable(false);
*/
// --------------------------------------------------------------------
// Nunchuck
// -----------------------------
// Stick controls
m_NunchuckTextStick[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Stick controls"));
m_NunchuckComboStick[i] = new wxComboBox(m_Controller[i], IDCB_NUNCHUCK_STICK, StrNunchuck[0], wxDefaultPosition, wxDefaultSize, StrNunchuck, wxCB_READONLY);
/*
m_NuZ[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
m_NuC[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
m_NuL[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
@ -909,11 +921,24 @@ void ConfigDialog::CreateGUIControls()
m_NuR[i]->Enable(false);
m_NuU[i]->Enable(false);
m_NuD[i]->Enable(false);
*/
// Sizers
m_NunchuckStick[i] = new wxBoxSizer(wxHORIZONTAL);
m_NunchuckStick[i]->Add(m_NunchuckTextStick[i], 0, (wxUP), 4);
m_NunchuckStick[i]->Add(m_NunchuckComboStick[i], 0, (wxLEFT), 2);
m_gNunchuck[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Nunchuck"));
m_gNunchuck[i]->Add(m_NunchuckStick[i], 0, (wxALL), 2);
//Set values
m_NunchuckComboStick[i]->SetSelection(g_Config.Nunchuck.Type);
// --------------------------------------------------------------------
// Classic Controller
// -----------------------------
m_gClassicController[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Classic Controller"));
/*
m_ClY[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
m_ClX[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
m_ClA[i] = new wxTextCtrl(m_Controller[i], ID_WM_A, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
@ -943,6 +968,17 @@ void ConfigDialog::CreateGUIControls()
m_ClLx[i]->Enable(false);
m_ClLy[i]->Enable(false);
*/
// --------------------------------------------------------------------
// Row 4 Sizers
// -----------------------------
m_HorizControllerMapping[i] = new wxBoxSizer(wxHORIZONTAL);
m_HorizControllerMapping[i]->AddStretchSpacer();
m_HorizControllerMapping[i]->Add(m_gWiimote[i]);
m_HorizControllerMapping[i]->Add(m_gNunchuck[i], 0, (wxLEFT), 5);
m_HorizControllerMapping[i]->Add(m_gClassicController[i], 0, (wxLEFT), 5);
m_HorizControllerMapping[i]->AddStretchSpacer();
///////////////////////////
@ -953,6 +989,7 @@ void ConfigDialog::CreateGUIControls()
m_SizeParent[i]->Add(m_SizeBasicGeneral[i], 0, wxBORDER_STATIC | wxEXPAND | (wxALL), 5);
m_SizeParent[i]->Add(m_HorizControllerTiltParent[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_SizeParent[i]->Add(m_HorizControllers[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
m_SizeParent[i]->Add(m_HorizControllerMapping[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5);
// The sizer m_sMain will be expanded inside m_Controller, m_SizeParent will not
m_sMain[i] = new wxBoxSizer(wxVERTICAL);
@ -1184,6 +1221,10 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
case IDC_JOYNAME:
DoChangeJoystick();
break;
case IDCB_NUNCHUCK_STICK:
g_Config.Nunchuck.Type = m_NunchuckComboStick[Page]->GetSelection();
break;
// These are defined in PadMapping and we can run the same function to update all of them
case IDCB_LEFT_DIAGONAL:
case IDC_LEFT_C2S:
@ -1193,11 +1234,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
break;
case IDCB_DEAD_ZONE_LEFT:
SaveButtonMappingAll(Page);
DoChangeDeadZone(true);
break;
case IDCB_DEAD_ZONE_RIGHT:
SaveButtonMappingAll(Page);
DoChangeDeadZone(false);
break;
//////////////////////////
@ -1261,6 +1300,9 @@ void ConfigDialog::UpdateGUI(int Slot)
// Update the gamepad settings
UpdateGUIButtonMapping(Page);
// Update dead zone
DoChangeDeadZone(true); DoChangeDeadZone(false);
/* We only allow a change of extension if we are not currently using the real Wiimote, if it's in use the status will be updated
from the data scanning functions in main.cpp */
bool AllowExtensionChange = !(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_Config.bUseRealWiimote && g_EmulatorRunning);

View File

@ -89,7 +89,8 @@ class ConfigDialog : public wxDialog
*m_SizeBasicGeneral[4], *m_SizeBasicGeneralLeft[4], *m_SizeBasicGeneralRight[4],
*m_HorizControllers[4], *m_gC2SDeadZone[4], *m_gCircle2Square[4], *m_gCircle2SquareVert[4], *m_gDeadZone[4], *m_gDeadZoneHoriz[4], *m_HorizControllerTiltParent[4], *m_HorizControllerTilt[4], *m_TiltHoriz[4],
*m_SizeAnalogLeft[4], *m_SizeAnalogLeftHorizX[4], *m_SizeAnalogLeftHorizY[4], *m_SizeAnalogRight[4], *m_SizeAnalogRightHorizX[4], *m_SizeAnalogRightHorizY[4],
*m_SizeAnalogTriggerVertLeft[4], *m_SizeAnalogTriggerVertRight[4], *m_SizeAnalogTriggerHorizInput[4];
*m_SizeAnalogTriggerVertLeft[4], *m_SizeAnalogTriggerVertRight[4], *m_SizeAnalogTriggerHorizInput[4],
*m_HorizControllerMapping[4], *m_NunchuckStick[4];
wxGridBagSizer *m_SizeAnalogTriggerHorizConfig[4], *m_SizeAnalogTriggerStatusBox[4], *m_TiltGrid[4],
*m_GridLeftStick[4], *m_GridRightStick[4];
wxStaticBoxSizer *m_SizeBasic[4], *m_SizeEmu[4], *m_SizeReal[4], *m_SizeExtensions[4], *m_gTilt[4], *m_gJoyname[4];
@ -100,13 +101,15 @@ class ConfigDialog : public wxDialog
wxStaticText *m_tAnalogX[8], *m_tAnalogY[8], *m_TiltTextRoll[4], *m_TiltTextPitch[4],
*m_CheckC2SLabel[4], *m_ComboDeadZoneLabel[4], *m_TStatusLeftIn[4], *m_TStatusLeftOut[4], *m_TStatusRightIn[4], *m_TStatusRightOut[4],
*m_TriggerStatusL[4], *m_TriggerStatusR[4], *m_TriggerStatusLx[4], *m_TriggerStatusRx[4],
*m_tAnalogTriggerInput[4], *m_tAnalogTriggerL[4], *m_tAnalogTriggerR[4];
*m_tAnalogTriggerInput[4], *m_tAnalogTriggerL[4], *m_tAnalogTriggerR[4],
*m_NunchuckTextStick[5];
// Emulated Wiimote settings
wxCheckBox *m_SidewaysDPad[4], *m_WiimoteOnline[4], *m_WideScreen[4];
wxCheckBox *m_CheckC2S[4], *m_TiltInvertRoll[4], *m_TiltInvertPitch[4];
wxCheckBox *m_WiiMotionPlusConnected[4], *m_NunchuckConnected[4], *m_ClassicControllerConnected[4], *m_BalanceBoardConnected[4], *m_GuitarHeroGuitarConnected[4], *m_GuitarHeroWorldTourDrumsConnected[4];
wxComboBox *m_TiltComboInput[4], *m_TiltComboRangeRoll[4], *m_TiltComboRangePitch[4], *m_Joyname[4], *m_ComboDiagonal[4], *m_ComboDeadZoneLeft[4], *m_ComboDeadZoneRight[4], *m_TriggerType[4];
wxComboBox *m_TiltComboInput[4], *m_TiltComboRangeRoll[4], *m_TiltComboRangePitch[4], *m_Joyname[4], *m_ComboDiagonal[4], *m_ComboDeadZoneLeft[4], *m_ComboDeadZoneRight[4], *m_TriggerType[4],
*m_NunchuckComboStick[4];
// Real Wiimote settings
wxCheckBox *m_ConnectRealWiimote[4], *m_UseRealWiimote[4], *m_UpdateMeters;
@ -114,7 +117,8 @@ class ConfigDialog : public wxDialog
wxPanel *m_pLeftInStatus[4], *m_pLeftOutStatus[4], *m_pRightInStatus[4], *m_pRightOutStatus[4];
wxStaticBitmap *m_bmpSquareLeftIn[4], *m_bmpSquareLeftOut[4], *m_bmpSquareRightIn[4], *m_bmpSquareRightOut[4];
wxStaticBoxSizer *m_gAnalogLeft[4], *m_gAnalogRight[4], *m_gTrigger[4];
wxStaticBoxSizer *m_gAnalogLeft[4], *m_gAnalogRight[4], *m_gTrigger[4],
*m_gWiimote[4], *m_gNunchuck[4], *m_gClassicController[4];
wxBitmap CreateBitmapDot(), CreateBitmap(), CreateBitmapDeadZone(int Radius), CreateBitmapClear();
wxButton * m_RecordButton[RECORDING_ROWS + 1];
@ -167,6 +171,7 @@ class ConfigDialog : public wxDialog
// Gamepad settings
IDC_JOYNAME, IDC_LEFT_C2S, IDCB_LEFT_DIAGONAL, IDCB_DEAD_ZONE_LEFT, IDCB_DEAD_ZONE_RIGHT,
ID_TRIGGER_TYPE, ID_TILT_INPUT, ID_TILT_RANGE_ROLL, ID_TILT_RANGE_PITCH, ID_TILT_INVERT_ROLL, ID_TILT_INVERT_PITCH,
IDCB_NUNCHUCK_STICK,
// Real
ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS, ID_NEUTRAL_CHOICE,

View File

@ -608,15 +608,11 @@ void ConfigDialog::PadGetStatus()
));
// Adjust the values for the plot
Convert2Box(main_x);
Convert2Box(main_y);
Convert2Box(right_x);
Convert2Box(right_y);
Convert2Box(main_x); Convert2Box(main_y);
Convert2Box(right_x); Convert2Box(right_y);
Convert2Box(main_x_after);
Convert2Box(main_y_after);
Convert2Box(right_x_after);
Convert2Box(right_y_after);
Convert2Box(main_x_after); Convert2Box(main_y_after);
Convert2Box(right_x_after); Convert2Box(right_y_after);
// Adjust the dot
m_bmpDotLeftIn[Page]->SetPosition(wxPoint(main_x, main_y));

View File

@ -575,6 +575,14 @@ void Update()
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
//Console::Print("Emu Update: %i\n", g_ReportingMode);
// Check if the pad state should be updated
if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2
|| g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1 || g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG2)
{
const int Page = 0;
WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page, joyinfo[PadMapping[Page].ID].NumButtons);
}
switch(g_ReportingMode)
{
case 0:

View File

@ -52,6 +52,7 @@ void SetDefaultExtensionRegistry();
// Gamepad
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads);
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons);
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr);
void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z);
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int&, int&);
float AccelerometerToG(float Current, float Neutral, float G);

View File

@ -74,8 +74,63 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
}
// ===========================
//////////////////////////////////////////////////////////////////////////////////////////
// Return adjusted input values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
{
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
// Request joystick state.
// Copy all states to a local variable
Lx = PadState[Page].Axis.Lx;
Ly = PadState[Page].Axis.Ly;
Rx = PadState[Page].Axis.Rx;
Ry = PadState[Page].Axis.Ry;
Tl = PadState[Page].Axis.Tl;
Tr = PadState[Page].Axis.Tr;
// Check the circle to square option
if(PadMapping[Page].bCircle2Square)
{
std::vector<int> main_xy = InputCommon::Square2Circle(Lx, Ly, Page, PadMapping[Page].SDiagonal, true);
Lx = main_xy.at(0);
Ly = main_xy.at(1);
}
// Dead zone adjustment
float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0;
float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0;
if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly))
{
Lx = 0;
Ly = 0;
}
if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry))
{
Rx = 0;
Ry = 0;
}
// Downsize the values from 0x8000 to 0x80
Lx = InputCommon::Pad_Convert(Lx);
Ly = InputCommon::Pad_Convert(Ly);
Rx = InputCommon::Pad_Convert(Rx);
Ry = InputCommon::Pad_Convert(Ry);
// The XInput range is already 0 to 0x80
if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
{
Tl = InputCommon::Pad_Convert(PadState[Page].Axis.Tl);
Tr = InputCommon::Pad_Convert(PadState[Page].Axis.Tr);
}
}
////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Request joystick state
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3
@ -84,6 +139,9 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
{
// Return if we have no pads
if (NumGoodPads == 0) return;
// Update the gamepad status
SDL_JoystickUpdate();
@ -130,6 +188,7 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
_PadState.Axis.Lx, _PadState.Axis.Ly
);*/
}
////////////////////////////////////////////
} // end of namespace WiiMoteEmu

View File

@ -356,56 +356,28 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch)
// Return if we have no pads
if (NumGoodPads == 0) return;
// Update the pad state
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page, joyinfo[PadMapping[Page].ID].NumButtons);
// Check if we should make adjustments
if(PadMapping[Page].bCircle2Square)
{
std::vector<int> main_xy = InputCommon::Square2Circle(PadState[Page].Axis.Lx, PadState[Page].Axis.Ly, Page, PadMapping[Page].SDiagonal, true);
PadState[Page].Axis.Lx = main_xy.at(0);
PadState[Page].Axis.Ly = main_xy.at(1);
}
// Check dead zone
float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0;
float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0;
if (InputCommon::IsDeadZone(DeadZoneLeft, PadState[Page].Axis.Lx, PadState[Page].Axis.Ly))
{
PadState[Page].Axis.Lx = 0;
PadState[Page].Axis.Ly = 0;
}
if (InputCommon::IsDeadZone(DeadZoneRight, PadState[Page].Axis.Rx, PadState[Page].Axis.Ry))
{
PadState[Page].Axis.Rx = 0;
PadState[Page].Axis.Ry = 0;
}
// Convert the big values
float Lx = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Lx);
float Ly = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Ly);
float Rx = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Rx);
float Ry = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Ry);
float Tl, Tr;
if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
{
Tl = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Tl);
Tr = (float)InputCommon::Pad_Convert(PadState[Page].Axis.Tr);
}
else
{
Tl = (float)PadState[Page].Axis.Tl;
Tr = (float)PadState[Page].Axis.Tr;
}
/* Adjust the pad state values, including a downscaling from the original 0x8000 size values
to 0x80. The only reason we do this is that the code below crrently assume that the range
is 0 to 255 for all axes. If we lose any precision by doing this we could consider not
doing this adjustment. And instead for example upsize the XInput trigger from 0x80 to 0x8000. */
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
float Lx = (float)_Lx;
float Ly = (float)_Ly;
float Rx = (float)_Rx;
float Ry = (float)_Ry;
float Tl = (float)_Tl;
float Tr = (float)_Tr;
// Save the Range in degrees, 45° and 90° are good values in some games
float RollRange = (float)g_Config.Trigger.Range.Roll;
float PitchRange = (float)g_Config.Trigger.Range.Pitch;
// The trigger currently only controls pitch
if (g_Config.Trigger.Type == g_Config.TRIGGER)
if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER)
{
// Make the range the same dimension as the analog stick
Tl = Tl / 2;
@ -413,36 +385,36 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch)
// Invert
if (PadMapping[Page].bPitchInvert) { Tl = -Tl; Tr = -Tr; }
// The final value
Pitch = Tl * (PitchRange / 128)
- Tr * (PitchRange / 128);
Pitch = Tl * (PitchRange / 128.0)
- Tr * (PitchRange / 128.0);
}
/* For the analog stick roll us by default set to the X-axis, pitch is by default set to the Y-axis.
By changing the axis mapping and the invert options this can be altered in any way */
else if (g_Config.Trigger.Type == g_Config.ANALOG1)
else if (g_Config.Trigger.Type == g_Config.Trigger.ANALOG1)
{
// Adjust the trigger to go between negative and positive values
Lx = Lx - 128;
Ly = Ly - 128;
Lx = Lx - 128.0;
Ly = Ly - 128.0;
// Invert
if (PadMapping[Page].bRollInvert) Lx = -Lx; // else Tr = -Tr;
if (PadMapping[Page].bPitchInvert) Ly = -Ly; // else Tr = -Tr;
// Produce the final value
Roll = Lx * (RollRange / 128);
Pitch = Ly * (PitchRange / 128);
Roll = Lx * (RollRange / 128.0);
Pitch = Ly * (PitchRange / 128.0);
}
// Otherwise we are using ANALOG2
else
{
// Adjust the trigger to go between negative and positive values
Rx = Rx - 128;
Ry = Ry - 128;
Rx = Rx - 128.0;
Ry = Ry - 128.0;
// Invert
if (PadMapping[Page].bRollInvert) Rx = -Rx; // else Tr = -Tr;
if (PadMapping[Page].bPitchInvert) Ry = -Ry; // else Tr = -Tr;
// Produce the final value
Roll = Rx * (RollRange / 128);
Pitch = Ry * (PitchRange / 128);
Roll = Rx * (RollRange / 128.0);
Pitch = Ry * (PitchRange / 128.0);
}
// Adjustment to prevent a slightly to high angle
@ -506,15 +478,15 @@ void TiltWiimoteKeyboard(float &Roll, float &Pitch)
void Tilt(u8 &_x, u8 &_y, u8 &_z)
{
// Ceck if it's on
if (g_Config.Trigger.Type == g_Config.TRIGGER_OFF) return;
if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER_OFF) return;
// Set to zero
float Roll = 0, Pitch = 0;
// Select input method and return the x, y, x values
if (g_Config.Trigger.Type == g_Config.KEYBOARD)
if (g_Config.Trigger.Type == g_Config.Trigger.KEYBOARD)
TiltWiimoteKeyboard(Roll, Pitch);
else if (g_Config.Trigger.Type == g_Config.TRIGGER || g_Config.Trigger.Type == g_Config.ANALOG1 || g_Config.Trigger.Type == g_Config.ANALOG2)
else if (g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2)
TiltWiimoteGamepad(Roll, Pitch);
// Adjust angles, it's only needed if both roll and pitch is used together
@ -932,16 +904,75 @@ void FillReportExtension(wm_extension& _ext)
// ---------------------
#ifdef _WIN32
// Set the max values to the current calibration values
if(GetAsyncKeyState(VK_NUMPAD4)) // x
_ext.jx = g_nu.jx.min;
if(GetAsyncKeyState(VK_NUMPAD6))
_ext.jx = g_nu.jx.max;
// Update the analog stick
if (g_Config.Nunchuck.Type == g_Config.Nunchuck.KEYBOARD)
{
// Set the max values to the current calibration values
if(GetAsyncKeyState(VK_NUMPAD4)) // x
_ext.jx = g_nu.jx.min;
if(GetAsyncKeyState(VK_NUMPAD6))
_ext.jx = g_nu.jx.max;
if(GetAsyncKeyState(VK_NUMPAD5)) // y
_ext.jy = g_nu.jy.min;
if(GetAsyncKeyState(VK_NUMPAD8))
_ext.jy = g_nu.jy.max;
if(GetAsyncKeyState(VK_NUMPAD5)) // y
_ext.jy = g_nu.jy.min;
if(GetAsyncKeyState(VK_NUMPAD8))
_ext.jy = g_nu.jy.max;
}
else
{
// Get adjusted pad state values
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
// The Y-axis is inverted
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
/* This is if we are also using a real Nunchuck that we are sharing the calibration with. It's not
needed if we are using our default values. We adjust the values to the configured range, we even
allow the center to not be 0x80. */
if(g_nu.jx.max != 0xff || g_nu.jy.max != 0xff
|| g_nu.jx.min != 0 || g_nu.jy.min != 0
|| g_nu.jx.center != 0x80 || g_nu.jy.center != 0x80)
{
float Lx = (float)_Lx;
float Ly = (float)_Ly;
float Rx = (float)_Rx;
float Ry = (float)_Ry;
float Tl = (float)_Tl;
float Tr = (float)_Tr;
float XRangePos = (float) (g_nu.jx.max - g_nu.jx.center);
float XRangeNeg = (float) (g_nu.jx.center - g_nu.jx.min);
float YRangePos = (float) (g_nu.jy.max - g_nu.jy.center);
float YRangeNeg = (float) (g_nu.jy.center - g_nu.jy.min);
if (Lx > 0x80) Lx = Lx * (XRangePos / 128.0);
if (Lx < 0x80) Lx = Lx * (XRangeNeg / 128.0);
if (Lx == 0x80) Lx = (float)g_nu.jx.center;
if (Ly > 0x80) Ly = Ly * (YRangePos / 128.0);
if (Ly < 0x80) Ly = Ly * (YRangeNeg / 128.0);
if (Ly == 0x80) Lx = (float)g_nu.jy.center;
// Boundaries
_Lx = (int)Lx;
_Ly = (int)Ly;
_Rx = (int)Rx;
_Ry = (int)Ry;
if (_Lx > 0xff) _Lx = 0xff; if (_Lx < 0) _Lx = 0;
if (_Rx > 0xff) _Rx = 0xff; if (_Rx < 0) _Rx = 0;
if (_Ly > 0xff) _Ly = 0xff; if (_Ly < 0) _Ly = 0;
if (_Ry > 0xff) _Ry = 0xff; if (_Ry < 0) _Ry = 0;
}
if (g_Config.Nunchuck.Type == g_Config.Nunchuck.ANALOG1)
{
_ext.jx = _Lx;
_ext.jy = _Ly;
}
else // ANALOG2
{
_ext.jx = _Rx;
_ext.jy = _Ry;
}
}
if(GetAsyncKeyState('C'))
_ext.bt = 0x01;

View File

@ -356,6 +356,10 @@ extern "C" void Wiimote_Update()
// Debugging
#ifdef _WIN32
// Open console
if( GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU) && GetAsyncKeyState(VK_INSERT) )
OpenConsole();
if( GetAsyncKeyState(VK_HOME) && g_DebugComm ) g_DebugComm = false; // Page Down
else if (GetAsyncKeyState(VK_HOME) && !g_DebugComm ) g_DebugComm = true;
@ -381,7 +385,36 @@ extern "C" unsigned int Wiimote_GetAttachedControllers()
// Supporting functions
//******************************************************************************
// ----------------------------------------
// Debugging window
// ----------
void OpenConsole(bool Open)
{
// Close the console window
if (Console::GetHwnd() != NULL && !Open)
{
Console::Close();
// Wait here until we have let go of the button again
while(GetAsyncKeyState(VK_INSERT)) {Sleep(10);}
return;
}
// Open the console window
Console::Open(130, 1000, "Wiimote"); // give room for 20 rows
Console::Print("\n\nWiimote console opened\n");
// Move window
//MoveWindow(Console::GetHwnd(), 0,400, 100*8,10*14, true); // small window
//MoveWindow(Console::GetHwnd(), 400,0, 100*8,70*14, true); // big window
MoveWindow(Console::GetHwnd(), 200,0, 130*8,70*14, true); // big wide window
}
// ---------------
// ----------------------------------------
// Check if Dolphin is in focus
// ----------
bool IsFocus()
{
#ifdef _WIN32
@ -416,7 +449,11 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
{
//
//const u8* data = (const u8*)_pData;
u8* data = (u8*)_pData;
//u8* data = (u8*)_pData;
// Copy the data to a new location that we know are the right size
u8 data[32];
memset(data, 0, sizeof(data));
memcpy(data, _pData, Size);
int size;
bool DataReport = false;
@ -612,23 +649,22 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
wiimote_decrypt(&WiiMoteEmu::g_ExtKey, &data[17], 0x00, 0x06);
// Produce string
std::string TmpData = ArrayToString(data, size + 2, 0, 30);
//std::string TmpData = ArrayToString(data, size + 2, 0, 30);
//LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
std::string TmpData = StringFromFormat(
"%02x %02x %02x %02x "
"%03i %03i %03i "
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
"%03i %03i %03i %03i %03i "
"%02x %02x ",
data[0], data[1], data[2], data[3], // Header and core buttons
data[4], data[5], data[6], // Wiimote accelerometer
data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16],
data[17], data[18], // Nunchuck stick
data[19], data[20], data[21], // Nunchuck Accelerometer
data[22], data[23] // Nunchuck buttons
);
// Format accelerometer values to regular 10 base values
if(TmpData.length() > 20)
{
std::string Tmp1 = TmpData.substr(0, 12);
std::string Tmp2 = TmpData.substr(20, (TmpData.length() - 20));
TmpData = Tmp1 + StringFromFormat("%03i %03i %03i", data[4], data[5], data[6]) + Tmp2;
}
// Format accelerometer values for the Nunchuck to regular 10 base values
if(TmpData.length() > 68 && WiiMoteEmu::g_ReportingMode == 0x37)
{
std::string Tmp1 = TmpData.substr(0, 60);
std::string Tmp2 = TmpData.substr(68, (TmpData.length() - 68));
TmpData = Tmp1 + StringFromFormat("%03i %03i %03i", data[19], data[20], data[21]) + Tmp2;
}
// Calculate the Wiimote roll and pitch in degrees
int Roll, Pitch, RollAdj, PitchAdj;
WiiMoteEmu::PitchAccelerometerToDegree(data[4], data[5], data[6], Roll, Pitch, RollAdj, PitchAdj);
@ -890,17 +926,8 @@ int GetUpdateRate()
void DoInitialize()
{
// ----------------------------------------
// Debugging window
// ----------
/*Console::Open(130, 1000, "Wiimote"); // give room for 20 rows
Console::Print("\n\nWiimote console opened\n");
// Move window
//MoveWindow(Console::GetHwnd(), 0,400, 100*8,10*14, true); // small window
//MoveWindow(Console::GetHwnd(), 400,0, 100*8,70*14, true); // big window
MoveWindow(Console::GetHwnd(), 200,0, 130*8,70*14, true); // big wide window*/
// ---------------
// Open console
//OpenConsole(true);
// Load config settings, will be done after the SDL functions in EmuMain.cpp
//g_Config.Load();

View File

@ -41,6 +41,7 @@ int GetUpdateRate();
void InterruptDebugging(bool Emu, const void* _pData);
void ReadDebugging(bool Emu, const void* _pData, int Size);
bool IsFocus();
void OpenConsole(bool Open = false);
// Movement recording