diff --git a/Source/Core/InputCommon/Src/Configuration.cpp b/Source/Core/InputCommon/Src/Configuration.cpp
index 44b5c05555..4756692974 100644
--- a/Source/Core/InputCommon/Src/Configuration.cpp
+++ b/Source/Core/InputCommon/Src/Configuration.cpp
@@ -94,6 +94,7 @@ float SquareDistance(float deg)
deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90;
+ // Calculate radians from degrees
float rad = deg * M_PI / 180;
float val = abs(cos(rad));
diff --git a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
index 0e0ebf7c0e..bb895fe527 100644
--- a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
+++ b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj
@@ -542,6 +542,10 @@
RelativePath=".\Src\EmuDefinitions.h"
>
+
+
diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
index 4d952bf4a9..cda5699198 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp
@@ -26,6 +26,7 @@ Config g_Config;
Config::Config()
{
+ // Set all default values to zero
memset(this, 0, sizeof(Config));
}
@@ -60,6 +61,8 @@ 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(), "TriggerRange", &Trigger.Range, 50);
// Don't update this when we are loading settings from the ConfigBox
if(!ChangePad)
@@ -67,6 +70,9 @@ void Config::Load(bool ChangePad)
iniFile.Get(SectionName.c_str(), "DeviceID", &WiiMoteEmu::PadMapping[i].ID, 0);
iniFile.Get(SectionName.c_str(), "Enabled", &WiiMoteEmu::PadMapping[i].enabled, true);
}
+
+ // Check if the pad ID is within the range of avaliable pads
+ if (WiiMoteEmu::PadMapping[i].ID > (WiiMoteEmu::NumPads - 1)) WiiMoteEmu::PadMapping[i].ID = (WiiMoteEmu::NumPads - 1);
// ===================
// ==================================================================
@@ -86,18 +92,18 @@ void Config::Load(bool ChangePad)
iniFile.Get(SectionName.c_str(), "left_y", &WiiMoteEmu::PadMapping[i].Axis.Ly, 1);
iniFile.Get(SectionName.c_str(), "right_x", &WiiMoteEmu::PadMapping[i].Axis.Rx, 2);
iniFile.Get(SectionName.c_str(), "right_y", &WiiMoteEmu::PadMapping[i].Axis.Ry, 3);
- iniFile.Get(SectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 4);
- iniFile.Get(SectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 5);
+ iniFile.Get(SectionName.c_str(), "l_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tl, 1004);
+ iniFile.Get(SectionName.c_str(), "r_trigger", &WiiMoteEmu::PadMapping[i].Axis.Tr, 1005);
iniFile.Get(SectionName.c_str(), "DeadZone", &WiiMoteEmu::PadMapping[i].deadzone, 0);
iniFile.Get(SectionName.c_str(), "TriggerType", &WiiMoteEmu::PadMapping[i].triggertype, 0);
iniFile.Get(SectionName.c_str(), "Diagonal", &WiiMoteEmu::PadMapping[i].SDiagonal, "100%");
- iniFile.Get(SectionName.c_str(), "SquareToCircle", &WiiMoteEmu::PadMapping[i].bSquareToCircle, false);
+ iniFile.Get(SectionName.c_str(), "SquareToCircle", &WiiMoteEmu::PadMapping[i].bSquareToCircle, false);
}
// =============================
Console::Print("Load()\n");
}
-void Config::Save()
+void Config::Save(int Slot)
{
IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "Wiimote.ini");
@@ -124,7 +130,9 @@ void Config::Save()
// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
std::string SectionName = StringFromFormat("Wiimote%i", i + 1);
iniFile.Set(SectionName.c_str(), "Enabled", WiiMoteEmu::PadMapping[i].enabled);
- iniFile.Set(SectionName.c_str(), "NoTriggerFilter", bNoTriggerFilter);
+ iniFile.Set(SectionName.c_str(), "NoTriggerFilter", bNoTriggerFilter);
+ iniFile.Set(SectionName.c_str(), "TriggerType", Trigger.Type);
+ iniFile.Set(SectionName.c_str(), "TriggerRange", Trigger.Range);
// Save the physical device ID number
iniFile.Set(SectionName.c_str(), "DeviceID", WiiMoteEmu::PadMapping[i].ID);
diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.h b/Source/Plugins/Plugin_Wiimote/Src/Config.h
index 7139eed991..264738f017 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/Config.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/Config.h
@@ -22,7 +22,21 @@ struct Config
{
Config();
void Load(bool ChangePad = false);
- void Save();
+ void Save(int Slot = -1);
+
+ struct PadTrigger
+ {
+ int Type;
+ int Range;
+ };
+
+ enum ETriggerType
+ {
+ TRIGGER_OFF = 0,
+ KEYBOARD,
+ ANALOG,
+ TRIGGER
+ };
// Emulated Wiimote
bool bSidewaysDPad;
@@ -36,6 +50,7 @@ struct Config
// Gamepad
bool bNoTriggerFilter;
+ PadTrigger Trigger;
};
extern Config g_Config;
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp
index 1896cd28cd..a7ca94f237 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp
@@ -101,6 +101,10 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
// Gamepad
EVT_COMBOBOX(ID_TRIGGER_TYPE, ConfigDialog::GeneralSettingsChanged)
+ EVT_COMBOBOX(ID_TILT_INPUT, ConfigDialog::GeneralSettingsChanged)
+ EVT_COMBOBOX(ID_TILT_RANGE, ConfigDialog::GeneralSettingsChanged)
+ EVT_COMBOBOX(IDC_JOYNAME, ConfigDialog::GeneralSettingsChanged)
+
EVT_BUTTON(IDB_ANALOG_LEFT_X, ConfigDialog::GetButtons)
EVT_BUTTON(IDB_ANALOG_LEFT_Y, ConfigDialog::GetButtons)
@@ -251,6 +255,47 @@ void ConfigDialog::UpdateOnce(wxTimerEvent& event)
//////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+// Save Settings
+/* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
+
+ Saving is currently done when:
+
+ 1. Closing the configuration window
+ 2. Changing the gamepad
+ 3. When the gamepad is enabled or disbled
+
+ Input: ChangePad needs to be used when we change the pad for a slot. Slot needs to be used when
+ we only want to save changes to one slot.
+*/
+void ConfigDialog::DoSave(bool ChangePad, int Slot)
+{
+ // Replace "" with "-1" before we are saving
+ ToBlank(false);
+
+ if(ChangePad)
+ {
+ // Since we are selecting the pad to save to by the Id we can't update it when we change the pad
+ for(int i = 0; i < 4; i++) SaveButtonMapping(i, true);
+
+ g_Config.Save(Slot);
+ // Now we can update the ID
+ WiiMoteEmu::PadMapping[Page].ID = m_Joyname[Page]->GetSelection();
+ }
+ else
+ {
+ // Update PadMapping[] from the GUI controls
+ for(int i = 0; i < 4; i++) SaveButtonMapping(i);
+ g_Config.Save(Slot);
+ }
+
+ // Then change it back to ""
+ ToBlank();
+}
+//////////////////////////////////////
+
+
//////////////////////////////////////////////////////////////////////////////////////////
// Bitmap box and dot
// ----------------
@@ -338,11 +383,12 @@ void ConfigDialog::CreateGUIControls()
// The tilt list
wxArrayString StrTilt;
StrTilt.Add(wxString::FromAscii(""));
+ StrTilt.Add(wxString::FromAscii("Keyboard"));
StrTilt.Add(wxString::FromAscii("Analog stick"));
StrTilt.Add(wxString::FromAscii("Triggers"));
- StrTilt.Add(wxString::FromAscii("Keyboard"));
+ // The range is in degrees and are set at even 5 degrees values
wxArrayString StrTiltRange;
- for (int i = 3; i < 15; i++) StrTiltRange.Add(wxString::Format(wxT("%i"), i*5));
+ for (int i = 2; i < 19; i++) StrTiltRange.Add(wxString::Format(wxT("%i"), i*5));
// The Trigger type list
wxArrayString StrTriggerType;
@@ -463,23 +509,27 @@ void ConfigDialog::CreateGUIControls()
// -----------------------------
/**/
// Controls
- m_TiltCombo[i] = new wxComboBox(m_Controller[i], ID_TILT_COMBO, StrTilt[0], wxDefaultPosition, wxDefaultSize, StrTilt, wxCB_READONLY);
- m_TiltComboRange[i] = new wxComboBox(m_Controller[i], wxID_ANY, StrTiltRange[0], wxDefaultPosition, wxDefaultSize, StrTiltRange, wxCB_READONLY);
+ m_TiltComboInput[i] = new wxComboBox(m_Controller[i], ID_TILT_INPUT, StrTilt[0], wxDefaultPosition, wxDefaultSize, StrTilt, wxCB_READONLY);
+ m_TiltComboRange[i] = new wxComboBox(m_Controller[i], ID_TILT_RANGE, StrTiltRange[0], wxDefaultPosition, wxDefaultSize, StrTiltRange, wxCB_READONLY);
m_TiltText[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Range"));
m_TiltHoriz[i] = new wxBoxSizer(wxHORIZONTAL);
m_TiltHoriz[i]->Add(m_TiltText[i], 0, (wxLEFT | wxTOP), 4);
m_TiltHoriz[i]->Add(m_TiltComboRange[i], 0, (wxLEFT | wxRIGHT), 5);
-
m_gTilt[i] = new wxStaticBoxSizer (wxVERTICAL, m_Controller[i], wxT("Tilt Wiimote"));
m_gTilt[i]->AddStretchSpacer();
- m_gTilt[i]->Add(m_TiltCombo[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_TiltHoriz[i], 0, wxEXPAND | (wxLEFT | wxRIGHT), 5);
m_gTilt[i]->AddStretchSpacer();
+ //Set values
+ m_TiltComboInput[i]->SetSelection(g_Config.Trigger.Type);
+ m_TiltComboRange[i]->SetValue(wxString::Format("%i", g_Config.Trigger.Range));
+
// Tooltips
- m_TiltCombo[i]->SetToolTip(wxT("Control tilting by an analog gamepad stick, an analog trigger or the keyboard."));
+ m_TiltComboInput[i]->SetToolTip(wxT("Control tilting by an analog gamepad stick, an analog trigger or the keyboard."));
+ m_TiltComboRange[i]->SetToolTip(wxT("The maximum tilt in degrees"));
// --------------------------------------------------------------------
// Analog triggers
@@ -938,6 +988,8 @@ void ConfigDialog::DoExtensionConnectedDisconnected(int Extension)
// ----------------
void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
{
+ long TmpValue;
+
switch (event.GetId())
{
case ID_CONNECT_REAL:
@@ -1006,6 +1058,15 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
case ID_TRIGGER_TYPE:
WiiMoteEmu::PadMapping[Page].triggertype = m_TriggerType[Page]->GetSelection();
break;
+ case ID_TILT_INPUT:
+ g_Config.Trigger.Type = m_TiltComboInput[Page]->GetSelection();
+ break;
+ case ID_TILT_RANGE:
+ m_TiltComboRange[Page]->GetValue().ToLong(&TmpValue); g_Config.Trigger.Range = TmpValue;
+ break;
+ case IDC_JOYNAME:
+ DoChangeJoystick();
+ break;
//////////////////////////
// Recording
@@ -1058,7 +1119,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
// =======================================================
// Update the enabled/disabled status
// -------------
-void ConfigDialog::UpdateGUI()
+void ConfigDialog::UpdateGUI(int Slot)
{
//Console::Print("UpdateGUI: \n");
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h
index 36ecc09bc0..8d4f245fb8 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h
@@ -44,7 +44,7 @@ class ConfigDialog : public wxDialog
// General open, close and event functions
void CloseClick(wxCommandEvent& event);
- void UpdateGUI(); void UpdateGUIButtonMapping(int controller);
+ void UpdateGUI(int Slot = 0); void UpdateGUIButtonMapping(int controller);
void OnKeyDown(wxKeyEvent& event);
void LoadFile(); void SaveFile();
@@ -103,7 +103,7 @@ class ConfigDialog : public wxDialog
wxCheckBox *m_SidewaysDPad[4], *m_WiimoteOnline[4];
wxCheckBox *m_WideScreen[4];
wxCheckBox *m_WiiMotionPlusConnected[4], *m_NunchuckConnected[4], *m_ClassicControllerConnected[4], *m_BalanceBoardConnected[4], *m_GuitarHeroGuitarConnected[4], *m_GuitarHeroWorldTourDrumsConnected[4];
- wxComboBox *m_TiltCombo[4], *m_TiltComboRange[4], *m_Joyname[4], *m_TriggerType[4];
+ wxComboBox *m_TiltComboInput[4], *m_TiltComboRange[4], *m_Joyname[4], *m_TriggerType[4];
// Real Wiimote settings
wxCheckBox *m_ConnectRealWiimote[4], *m_UseRealWiimote[4], *m_UpdateMeters;
@@ -147,7 +147,7 @@ class ConfigDialog : public wxDialog
ID_SIDEWAYSDPAD, // Emulated
ID_WIDESCREEN,
ID_NUNCHUCKCONNECTED, ID_CLASSICCONTROLLERCONNECTED,
- IDC_JOYNAME, IDC_JOYATTACH, ID_TILT_COMBO, ID_TILT_CHECK,
+ IDC_JOYNAME, IDC_JOYATTACH,
// Gamepad
IDB_ANALOG_LEFT_X, IDB_ANALOG_LEFT_Y,
@@ -159,7 +159,7 @@ class ConfigDialog : public wxDialog
ID_TRIGGER_L, ID_TRIGGER_R,
// Gamepad settings
- ID_TRIGGER_TYPE,
+ ID_TRIGGER_TYPE, ID_TILT_INPUT, ID_TILT_RANGE,
// Real
ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS, ID_NEUTRAL_CHOICE,
@@ -186,6 +186,8 @@ class ConfigDialog : public wxDialog
void SaveButtonMapping(int controller, bool DontChangeId = false, int FromSlot = -1); void SaveButtonMappingAll(int Slot);
void ToBlank(bool ToBlank = true);
void PadGetStatus();
+ void DoSave(bool ChangePad = false, int Slot = -1);
+ void DoChangeJoystick(); void PadOpen(int Open); void PadClose(int Close);
// Configure buttons
int GetButtonWaitingID, GetButtonWaitingTimer;
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
index 34be1853c7..b0eb4f4eea 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigGamepad.cpp
@@ -35,6 +35,48 @@
//////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
+// Change Joystick
+// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
+/* Function: When changing the joystick we save and load the settings and update the PadMapping
+ and PadState array. PadState[].joy is the gamepad handle that is used to access the pad throughout
+ the plugin. Joyinfo[].joy is only used the first time the pads are checked. */
+void ConfigDialog::DoChangeJoystick()
+{
+ // Close the current pad, unless it's used by another slot
+ //if (PadMapping[notebookpage].enabled) PadClose(notebookpage);
+
+ // Before changing the pad we save potential changes to the current pad
+ DoSave(true);
+
+ // Load the settings for the new Id
+ g_Config.Load(true);
+ UpdateGUI(Page); // Update the GUI
+
+ // Open the new pad
+ if (WiiMoteEmu::PadMapping[Page].enabled) PadOpen(Page);
+}
+void ConfigDialog::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
+{
+ // Check that we got a good pad
+ if (!WiiMoteEmu::joyinfo.at(WiiMoteEmu::PadMapping[Open].ID).Good)
+ {
+ Console::Print("A bad pad was selected\n");
+ WiiMoteEmu::PadState[Open].joy = NULL;
+ return;
+ }
+
+ Console::Print("Update the Slot %i handle to Id %i\n", Page, WiiMoteEmu::PadMapping[Open].ID);
+ WiiMoteEmu::PadState[Open].joy = SDL_JoystickOpen(WiiMoteEmu::PadMapping[Open].ID);
+}
+void ConfigDialog::PadClose(int Close) // Close for slot 1, 2, 3 or 4
+{
+ if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[Close].joy);
+ WiiMoteEmu::PadState[Close].joy = NULL;
+}
+//////////////////////////////////////
+
+
///////////////////////////////////////////////////////////////////////////////////
// Change settings
// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
@@ -368,6 +410,9 @@ void ConfigDialog::DoGetButtons(int GetId)
have the same id, I don't know. So we have to do this. The user may also have selected the same device for
several disabled slots. */
SaveButtonMappingAll(Controller);
+
+ Console::Print("Timer Stopped for Pad:%i GetId:%i\n",
+ WiiMoteEmu::PadMapping[Controller].ID, GetId);
}
// If we got a bad button
@@ -429,9 +474,9 @@ void ConfigDialog::PadGetStatus()
// Get physical device status
int PhysicalDevice = WiiMoteEmu::PadMapping[Page].ID;
int TriggerType = WiiMoteEmu::PadMapping[Page].triggertype;
-
+
// Check that Dolphin is in focus, otherwise don't update the pad status
- if (IsFocus())
+ //if (IsFocus())
WiiMoteEmu::GetJoyState(WiiMoteEmu::PadState[Page], WiiMoteEmu::PadMapping[Page], Page, WiiMoteEmu::joyinfo[WiiMoteEmu::PadMapping[Page].ID].NumButtons);
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp
index 06195ef474..954a67151a 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp
@@ -110,6 +110,7 @@ void ConfigDialog::SaveFile()
}
file.Save("WiimoteMovement.ini");
+ Console::Print("Wrote WiimoteMovement.ini\n");
}
/////////////////////////////
@@ -413,6 +414,8 @@ void ConfigDialog::ConvertToString()
}
file.Save("WiimoteMovement.ini");
+
+ Console::Print("Save recording to WiimoteMovement.ini\n");
}
// Timeout the recording
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp
new file mode 100644
index 0000000000..a06b0ff335
--- /dev/null
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp
@@ -0,0 +1,102 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Includes
+// ŻŻŻŻŻŻŻŻŻŻŻŻŻ
+#include
+#include
+
+#include "../../../Core/InputCommon/Src/SDL.h" // Core
+#include "../../../Core/InputCommon/Src/XInput.h"
+
+#include "Common.h" // Common
+#include "StringUtil.h" // for ArrayToString()
+#include "IniFile.h"
+#include "pluginspecs_wiimote.h"
+
+#include "EmuDefinitions.h" // Local
+#include "main.h"
+#include "wiimote_hid.h"
+#include "EmuSubroutines.h"
+#include "EmuMain.h"
+#include "Encryption.h" // for extension encryption
+#include "Logging.h" // for startConsoleWin, Console::Print, GetConsoleHwnd
+#include "Config.h" // for g_Config
+////////////////////////////////////
+
+
+namespace WiiMoteEmu
+{
+
+void PitchDegreeToAccelerometer(float _Degree, u8 &_y, u8 &_z)
+{
+ // Calculate the radian
+ float d_rad = _Degree * M_PI / 180.0;
+
+ // Calculate a good set of y and z values for the degree
+ float r = 1.0;
+ float fy = r * sin(d_rad); // y
+ float fz = r * cos(d_rad); // x
+
+ // Multiple with the neutral of z and its g
+ float yg = g_accel.cal_g.y;
+ float zg = g_accel.cal_g.z;
+ float y_zero = g_accel.cal_zero.y;
+ float z_zero = g_accel.cal_zero.z;
+ fy = (int) (y_zero + yg * fy);
+ fz = (int) (z_zero + zg * fz);
+
+ // Boundaries
+ int iy = (int)fy;
+ int iz = (int)fz;
+ if (iy < 0) iy = 0;
+ if (iy > 255) iy = 255;
+ _y = iy;
+ _z = iz;
+}
+
+
+int PitchAccelerometerToDegree(u8 _y, u8 _z)
+{
+ /* find out how much it has to move to be 1g */
+ float yg = (float)g_accel.cal_g.y;
+ float zg = (float)g_accel.cal_g.z;
+ float d = 0;
+
+ /* find out how much it actually moved and normalize to +/- 1g */
+ float y = ((float)_y - (float)g_accel.cal_zero.y) / yg;
+ float z = ((float)_z - (float)g_accel.cal_zero.z) / zg;
+
+ /* make sure x,y,z are between -1 and 1 for the tan function */
+ if (y < -1.0) y = -1.0;
+ else if (y > 1.0) y = 1.0;
+ if (z < -1.0) z = -1.0;
+ else if (z > 1.0) z = 1.0;
+
+ //if (abs(_y - g_accel.cal_zero.y) <= g_accel.cal_g.y)
+ {
+ // Calculate the radian
+ d = atan2(y, z);
+ // Calculate the degree
+ d = (d * 180.0) / M_PI;
+ }
+ return (int)d;
+}
+
+}
\ No newline at end of file
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
index 6a86ef0b3b..a285b883a0 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp
@@ -123,6 +123,8 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
// ----------------
void LoadRecordedMovements()
{
+ Console::Print("LoadRecordedMovements()");
+
IniFile file;
file.Load("WiimoteMovement.ini");
@@ -131,6 +133,9 @@ void LoadRecordedMovements()
// Logging
//Console::Print("Recording%i ", i + 1);
+ // First clear the list
+ VRecording.at(i).Recording.clear();
+
// Get row name
std::string SaveName = StringFromFormat("Recording%i", i + 1);
@@ -192,10 +197,10 @@ void LoadRecordedMovements()
// ---------------------------------
// Log results
// ---------
- //Console::Print("Time:%f\n", Tmp.Time);
- //std::string TmpIRLog = ArrayToString(Tmp.IR, TmpIRBytes, 0, 30);
- //Console::Print("IR: %s\n", TmpIRLog.c_str());
- //Console::Print("\n");
+ /*Console::Print("Time:%f\n", Tmp.Time);
+ std::string TmpIRLog = ArrayToString(Tmp.IR, TmpIRBytes, 0, 30);
+ Console::Print("IR: %s\n", TmpIRLog.c_str());
+ Console::Print("\n");*/
}
// Get HotKey
@@ -216,7 +221,7 @@ void LoadRecordedMovements()
TmpIRLog = "";
/*
- Console::Print("Size:%i HotKey:%i Speed:%i IR: %s\n",
+ Console::Print("Size:%i HotKey:%i PlSpeed:%i IR: %s\n",
VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed,
TmpIRLog.c_str()
);*/
@@ -465,10 +470,13 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
and registry reads and writes. */
// There are no 0x22 replys to these report from the real wiimote from what I could see
- // Report 0x10 that seems to be only used for rumble
+ // Report 0x10 that seems to be only used for rumble, and we don't need to answer that,
+ // also if we do *we should update the 0x22 to have the core keys* otherwise the game will
+ // think we release the key every time it rumbles
if(!(data[1] == WM_READ_DATA && data[2] == 0x00)
&& !(data[1] == WM_REQUEST_STATUS)
- && !(data[1] == WM_WRITE_SPEAKER_DATA))
+ && !(data[1] == WM_WRITE_SPEAKER_DATA)
+ && !(data[1] == WM_RUMBLE))
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel);
}
break;
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
index f375b548e7..2cfaf5dfc7 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h
@@ -51,6 +51,11 @@ void SetDefaultExtensionRegistry();
// Gamepad
bool Search_Devices(std::vector &_joyinfo, int &_NumPads, int &_NumGoodPads);
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons);
-};
+void PitchDegreeToAccelerometer(float _Degree, u8 &_y, u8 &_z);
+int PitchAccelerometerToDegree(u8 _y, u8 _z);
+
+
+}; // WiiMoteEmu
+
#endif
diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
index f780d9aad4..48ec100931 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/EmuPad.cpp
@@ -99,8 +99,10 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
{
#endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
- _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000);
- _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000);
+ // We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has
+ // no good way of handling that
+ if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000);
+ if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000);
#ifdef _WIN32
}
else
@@ -115,13 +117,17 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
Console::Print(
"Controller and handle: %i %i\n"
- "Triggers:%i %i %i %i %i\n",
+ "Triggers:%i %i %i %i %i\n"
+
+ "Analog:%06i %06i \n",
controller, (int)_PadState.joy,
_PadMapping.triggertype,
_PadMapping.Axis.Tl, _PadMapping.Axis.Tr,
- _PadState.Axis.Tl, _PadState.Axis.Tr
+ _PadState.Axis.Tl, _PadState.Axis.Tr,
+
+ _PadState.Axis.Lx, _PadState.Axis.Ly
);*/
}
diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
index d713ac334b..0692395723 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp
@@ -139,8 +139,10 @@ bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm)
VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).Time, g_RecordingCurrentTime[Wm],
VRecording.at(g_RecordingPlaying[Wm]).Recording.size(), g_RecordingPoint[Wm]
);
- Console::Print("Accel x, y, z: %03u %03u %03u\n\n", _x, _y, _z);
+ Console::Print("Accel x, y, z: %03u %03u %03u\n", _x, _y, _z);
}
+ //Console::Print("Accel x, y, z: %03u %03u %03u\n", _x, _y, _z);
+ //Console::Print("Accel x, y, z: %02x %02x %02x\n", _x, _y, _z);
g_RecordingCounter[Wm]++;
@@ -233,6 +235,15 @@ int RecordingCheckKeys(int Wiimote)
#endif
}
+// check if we have any recording playback key combination
+bool CheckKeyCombination()
+{
+ if (RecordingCheckKeys(0) == -1 && RecordingCheckKeys(1) == -1 && RecordingCheckKeys(2) == -1)
+ return false;
+ else
+ return true; // This will also start a recording
+}
+
//******************************************************************************
@@ -253,6 +264,9 @@ void FillReportInfo(wm_core& _core)
// Check that Dolphin is in focus
if (!IsFocus()) return;
+ // Don't interrupt a recording
+ if (CheckKeyCombination()) return;
+
// Check the mouse position. Don't allow mouse clicks from outside the window.
float x, y; GetMousePos(x, y);
bool InsideScreen = !(x < 0 || x > 1 || y < 0 || y > 1);
@@ -299,22 +313,173 @@ void FillReportInfo(wm_core& _core)
being [y = 0x84, x = 0x84, z = 0x9f] according to a 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 permanently then, until z is adjusted back. */
+
+
// ----------
// Global declarations for FillReportAcc: These variables are global so they 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;
-u8 x, y, z;
-int shake = -1, yhistsize = 15; // for the shake function
-std::vector yhist(15); // for the tilt function
+// For all functions
+u8 x, y, z, X, Y, Z;
+
+// For the shake function
+int shake = -1;
+
+// For the tilt function, the size of this list determines how fast Y returns to its neutral value
+std::vector yhist(15, 0); float KbDegree;
+
+
+// ------------------------------------------
+// Single shake of Wiimote while holding it sideways (Wario Land pound ground)
+// ---------------
+void SingleShake(u8 &_z, u8 &_y)
+{
+ if(GetAsyncKeyState('S'))
+ {
+ _z = 0;
+ _y = 0;
+ shake = 2;
+ }
+ else if(shake == 2)
+ {
+ _z = 128;
+ _y = 0;
+ shake = 1;
+ }
+ else if(shake == 1)
+ {
+ _z = Z;
+ _y = Y;
+ shake = -1;
+ }
+ else // the default Z if nothing is pressed
+ {
+ z = Z;
+ }
+}
+
+// ------------------------------------------
+/* Tilting Wiimote with gamepad. We can guess that the game will calculate a Wiimote pitch and use it as a
+ measure of the tilting of the Wiimote. We are interested in this tilting range
+ 90° to -90° */
+// ---------------
+void TiltWiimoteGamepad(u8 &_y, u8 &_z)
+{
+ // Update the pad state
+ const int Page = 0;
+ WiiMoteEmu::GetJoyState(PadState[Page], PadMapping[Page], Page, joyinfo[PadMapping[Page].ID].NumButtons);
+
+ // 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;
+ }
+
+ // It's easier to use a float here
+ float Degree = 0;
+ // Calculate the present room between the neutral and the maximum values
+ float RoomAbove = 255.0 - (float)Y;
+ float RoomBelow = (float)Y;
+ // Save the Range in degrees, 45° and 90° are good values in some games
+ float Range = (float)g_Config.Trigger.Range;
+
+ // Trigger
+ if (g_Config.Trigger.Type == g_Config.TRIGGER)
+ {
+ // Make the range the same dimension as the analog stick
+ Tl = Tl / 2;
+ Tr = Tr / 2;
+
+ Degree = Tl * (Range / 128)
+ - Tr * (Range / 128);
+ }
+
+ // Analog stick
+ else
+ {
+ // Adjust the trigger to go between negative and positive values
+ Lx = Lx - 128;
+ // Produce the final value
+ Degree = -Lx * (Range / 128);
+ }
+
+ // Calculate the acceleometer value from this tilt angle
+ PitchDegreeToAccelerometer(Degree, _y, _z);
+
+ //Console::ClearScreen();
+ /*Console::Print("L:%2.1f R:%2.1f Lx:%2.1f Range:%2.1f Degree:%2.1f L:%i R:%i\n",
+ Tl, Tr, Lx, Range, Degree, PadState[Page].Axis.Tl, PadState[Page].Axis.Tr);*/
+ /*Console::Print("Degree:%2.1f\n", Degree);*/
+}
+
+
+// ------------------------------------------
+// Tilting Wiimote (Wario Land aiming, Mario Kart steering) : For some reason 150 and 40
+// seemed like decent starting values.
+// ---------------
+void TiltWiimoteKeyboard(u8 &_y, u8 &_z)
+{
+#ifdef _WIN32
+ if(GetAsyncKeyState('3'))
+ {
+ // Stop at the upper end of the range
+ if(KbDegree < g_Config.Trigger.Range)
+ KbDegree += 3; // aim left
+ }
+ else if(GetAsyncKeyState('4'))
+ {
+ // Stop at the lower end of the range
+ if(KbDegree > -g_Config.Trigger.Range)
+ KbDegree -= 3; // aim right
+ }
+
+ // -----------------------------------
+ // Check for inactivity in the tilting, the Y value will be reset after ten inactive updates
+ // ----------
+
+ yhist[yhist.size() - 1] = (
+ GetAsyncKeyState('3')
+ || GetAsyncKeyState('4')
+ || shake > 0
+ );
+
+ // Move all items back, and check if any of them are true
+ bool ypressed = false;
+ for (int i = 1; i < (int)yhist.size(); i++)
+ {
+ yhist[i-1] = yhist[i];
+ if(yhist[i]) ypressed = true;
+ }
+ // Tilting was not used a single time, reset y to its neutral value
+ if(!ypressed)
+ {
+ _y = Y;
+ }
+ else
+ {
+ PitchDegreeToAccelerometer(KbDegree, _y, _z);
+ //Console::Print("Degree: %2.1f\n", KbDegree);
+ }
+ // --------------------
+#endif
+}
void FillReportAcc(wm_accel& _acc)
{
- // Create shortcut names for the default neutral values
- int X = g_accel.cal_zero.x, Y = g_accel.cal_zero.y, Z = g_accel.cal_zero.z + g_accel.cal_g.z;
-
-#ifdef _WIN32
// ------------------------------------
// Recorded movements
// --------------
@@ -331,6 +496,11 @@ void FillReportAcc(wm_accel& _acc)
}
// ---------------------
+ // The default values can change so we need to update them all the time
+ X = g_accel.cal_zero.x;
+ Y = g_accel.cal_zero.y;
+ Z = g_accel.cal_zero.z + g_accel.cal_g.z;
+
// Check that Dolphin is in focus
if (!IsFocus())
@@ -341,102 +511,24 @@ void FillReportAcc(wm_accel& _acc)
return;
}
- // ------------------------------------
+ // ------------------------------------------------
// Wiimote to Gamepad translations
- // ----------
- // Tilting Wiimote (Wario Land aiming, Mario Kart steering) : For some reason 150 and 40
- // seemed like decent starting values.
- if(GetAsyncKeyState('3'))
- {
- //if(a < 128) // for debugging
- if(y < 250)
- {
- y += 4; // aim left
- //a += c; // debugging values
- //y = A + a; // aim left
- }
- }
- else if(GetAsyncKeyState('4'))
- {
- // if(b < 128) // for debugging
- if(y > 5)
- {
- y -= 4; // aim right
- //b -= d; // debugging values
- //y = B + b;
- }
- }
+ // ------------
- /* Single shake of Wiimote while holding it sideways (Wario Land pound ground)
- if(GetAsyncKeyState('S'))
- z = 0;
- else
- z = Z;*/
-
- if(GetAsyncKeyState('S'))
- {
- z = 0;
- y = 0;
- shake = 2;
- }
- else
-#endif
- if(shake == 2)
- {
- z = 128;
- y = 0;
- shake = 1;
- }
- else if(shake == 1)
- {
- z = Z;
- y = Y;
- shake = -1;
- }
- else // the default Z if nothing is pressed
- {
- z = Z;
- }
- // ----------
-
-
- // -----------------------------
- // For tilting: add new value and move all back
- // ----------
- bool ypressed = false;
-
-#ifdef _WIN32
- yhist[yhist.size() - 1] = (
- GetAsyncKeyState('3') ? true : false
- || GetAsyncKeyState('4') ? true : false
- || shake > 0
- );
-#endif
- if(yhistsize > (int)yhist.size()) yhistsize = (int)yhist.size();
- for (int i = 1; i < yhistsize; i++)
- {
- yhist[i-1] = yhist[i];
- if(yhist[i]) ypressed = true;
- }
-
- if(!ypressed) // y was not pressed a single time
- {
- y = Y; // this is the default value that will occur most of the time
- //a = 0; // for debugging
- //b = 0;
- }
- // else if(!GetAsyncKeyState('3') && !GetAsyncKeyState('4'))
- // {
- // perhaps start dropping acceleration back?
- // }
- // ----------
+ // Shake the Wiimote
+ SingleShake(z, y);
+ // Tilt Wiimote
+ if (g_Config.Trigger.Type == g_Config.KEYBOARD)
+ TiltWiimoteKeyboard(y, z);
+ else if (g_Config.Trigger.Type == g_Config.TRIGGER || g_Config.Trigger.Type == g_Config.ANALOG)
+ TiltWiimoteGamepad(y, z);
// Write values
_acc.x = X;
_acc.y = y;
_acc.z = z;
-
+
// ----------------------------
// Debugging for translating Wiimote to Keyboard (or Gamepad)
diff --git a/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp b/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp
index 40739c8b0d..8bc48a40cc 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp
@@ -198,13 +198,14 @@ void handle_event(struct wiimote_t* wm)
frame->m_GaugeAccel[2]->SetValue(AccelZ);
frame->m_TextIR->SetLabel(wxString::Format(
- wxT("Cursor: %03u %03u\nDistance:%4.0f"), wm->ir.x, wm->ir.y, wm->ir.z));
+ wxT("Cursor: %03u %03u\nDistance:%4.0f"), wm->ir.x, wm->ir.y, wm->ir.z));
frame->m_TextAccNeutralCurrent->SetLabel(wxString::Format(
- wxT("Current: %03u %03u %03u"), AccelX, AccelY, AccelZ));
+ wxT("Current: %03u %03u %03u"), AccelX, AccelY, AccelZ));
if(frame->m_bRecording)
Console::Print("Wiiuse Recorded accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z);
+ //Console::Print("Wiiuse Recorded accel x, y, z: %02x %02x %02x\n", wm->accel.x, wm->accel.y, wm->accel.z);
}
// Send the data to be saved
diff --git a/Source/Plugins/Plugin_Wiimote/Src/SConscript b/Source/Plugins/Plugin_Wiimote/Src/SConscript
index 2ea2af9672..6f8b8d2546 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/SConscript
+++ b/Source/Plugins/Plugin_Wiimote/Src/SConscript
@@ -10,6 +10,7 @@ files = [
"Config.cpp",
"DataReports.cpp",
"EmuDefinitions.cpp",
+ "EmuDynamics.cpp",
"EmuMain.cpp",
"EmuPad.cpp",
"EmuSubroutines.cpp",
diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp
index a584618630..e4ca419653 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp
+++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp
@@ -408,6 +408,7 @@ void DisableExtensions()
//g_Config.bDrums = false;
}
+
void ReadDebugging(bool Emu, const void* _pData, int Size)
{
//
@@ -625,8 +626,10 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
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 pitch in degrees
+ std::string Pitch = StringFromFormat("%i", WiiMoteEmu::PitchAccelerometerToDegree(data[5], data[6]));
- Console::Print("Read[%s]: %s\n", (Emu ? "Emu" : "Real"), TmpData.c_str()); // No timestamp
+ Console::Print("Read[%s]: %s| %s\n", (Emu ? "Emu" : "Real"), TmpData.c_str(), Pitch.c_str()); // No timestamp
//Console::Print(" (%s): %s\n", Tm(true).c_str(), Temp.c_str()); // Timestamp
}
if(g_DebugAccelerometer)
diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h
index 503ad7a565..7162ae03d8 100644
--- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h
+++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h
@@ -49,6 +49,7 @@ struct wm_report {
u8 data[0];
};
+#define WM_RUMBLE 0x10
#define WM_LEDS 0x11
struct wm_leds {
u8 rumble : 1;
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
index 87b314ba22..f9e8ad23f1 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/GUI/ConfigJoypad.cpp
@@ -286,7 +286,8 @@ void ConfigBox::DoGetButtons(int GetId)
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R)
- && !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); // Don't allow SDL here
+ // Don't allow SDL input for the triggers when XInput is selected
+ && !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) );
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);