From fe5fb76fd49308dea2d932d118295c403d2ff192 Mon Sep 17 00:00:00 2001 From: dapetcu21 Date: Tue, 13 Apr 2010 01:34:11 +0000 Subject: [PATCH] Added UDPWii (iPhone WiiMote) support. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5351 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Dolphin.xcodeproj/project.pbxproj | 8 + Source/Plugins/Plugin_Wiimote/Src/Config.cpp | 20 ++ .../Plugin_Wiimote/Src/ConfigBasicDlg.cpp | 71 ++++++ .../Plugin_Wiimote/Src/ConfigBasicDlg.h | 27 ++- .../Plugin_Wiimote/Src/EmuDefinitions.h | 14 ++ .../Plugin_Wiimote/Src/EmuDynamics.cpp | 22 +- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 11 + .../Plugins/Plugin_Wiimote/Src/FillReport.cpp | 76 ++++-- Source/Plugins/Plugin_Wiimote/Src/SConscript | 1 + .../Plugins/Plugin_Wiimote/Src/UDPWiimote.cpp | 222 ++++++++++++++++++ .../Plugins/Plugin_Wiimote/Src/UDPWiimote.h | 44 ++++ 11 files changed, 485 insertions(+), 31 deletions(-) create mode 100644 Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.cpp create mode 100644 Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.h diff --git a/Source/Dolphin.xcodeproj/project.pbxproj b/Source/Dolphin.xcodeproj/project.pbxproj index 41fc679efd..ec49ecc948 100644 --- a/Source/Dolphin.xcodeproj/project.pbxproj +++ b/Source/Dolphin.xcodeproj/project.pbxproj @@ -810,6 +810,8 @@ B1EDF579106C2DAE0003EAE6 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1EDF564106C2CD70003EAE6 /* CoreAudio.framework */; }; B1EDF582106C2E000003EAE6 /* Render.h in Headers */ = {isa = PBXBuildFile; fileRef = B1EDF581106C2E000003EAE6 /* Render.h */; }; B1EDF583106C2E000003EAE6 /* Render.h in Headers */ = {isa = PBXBuildFile; fileRef = B1EDF581106C2E000003EAE6 /* Render.h */; }; + C1CE233A116A4C0200347EB3 /* UDPWiimote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C1CE2338116A4C0200347EB3 /* UDPWiimote.cpp */; }; + C1CE233B116A4C0200347EB3 /* UDPWiimote.h in Headers */ = {isa = PBXBuildFile; fileRef = C1CE2339116A4C0200347EB3 /* UDPWiimote.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1925,6 +1927,8 @@ B1EDF55B106C2CBA0003EAE6 /* CoreAudioSoundStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudioSoundStream.h; sourceTree = ""; }; B1EDF564106C2CD70003EAE6 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; B1EDF581106C2E000003EAE6 /* Render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render.h; sourceTree = ""; }; + C1CE2338116A4C0200347EB3 /* UDPWiimote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UDPWiimote.cpp; sourceTree = ""; }; + C1CE2339116A4C0200347EB3 /* UDPWiimote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UDPWiimote.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2496,6 +2500,8 @@ B122DB4F1003548600D86E1A /* Src */ = { isa = PBXGroup; children = ( + C1CE2338116A4C0200347EB3 /* UDPWiimote.cpp */, + C1CE2339116A4C0200347EB3 /* UDPWiimote.h */, B122DB501003548600D86E1A /* Config.cpp */, B122DB511003548600D86E1A /* Config.h */, B122DB5A1003548600D86E1A /* DataReports.cpp */, @@ -3727,6 +3733,7 @@ B122DB841003548600D86E1A /* main.h in Headers */, B122DB861003548600D86E1A /* wiimote_hid.h in Headers */, B122DB881003548600D86E1A /* wiimote_real.h in Headers */, + C1CE233B116A4C0200347EB3 /* UDPWiimote.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4702,6 +4709,7 @@ B122DB831003548600D86E1A /* main.cpp in Sources */, B122DB851003548600D86E1A /* ReadWiimote.cpp in Sources */, B122DB871003548600D86E1A /* wiimote_real.cpp in Sources */, + C1CE233A116A4C0200347EB3 /* UDPWiimote.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp index fcb95c4a83..69edfeb5c7 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/Config.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/Config.cpp @@ -324,6 +324,18 @@ void Config::Load() iniFile.Get(SectionName, "Rumble", &WiiMoteEmu::WiiMapping[i].Rumble, false); iniFile.Get(SectionName, "RumbleStrength", &WiiMoteEmu::WiiMapping[i].RumbleStrength, 80); iniFile.Get(SectionName, "TriggerType", &WiiMoteEmu::WiiMapping[i].TriggerType, 0); + + //UDPWii + iniFile.Get(SectionName, "UDPWii_Enable", &WiiMoteEmu::WiiMapping[i].UDPWM.enable, false); + std::string port; + char default_port[15]; + sprintf(default_port,"%d",4432+i); + iniFile.Get(SectionName, "UDPWii_Port", &port, default_port); + strncpy(WiiMoteEmu::WiiMapping[i].UDPWM.port,port.c_str(),10); + iniFile.Get(SectionName, "UDPWii_EnableAccel", &WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel, true); + iniFile.Get(SectionName, "UDPWii_EnableButtons", &WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons, true); + iniFile.Get(SectionName, "UDPWii_EnableIR", &WiiMoteEmu::WiiMapping[i].UDPWM.enableIR, true); + iniFile.Get(SectionName, "UDPWii_EnableNunchuck", &WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck, true); } iniFile.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Dolphin.ini").c_str()); @@ -430,6 +442,14 @@ void Config::Save() iniFile.Set(SectionName, "Rumble", WiiMoteEmu::WiiMapping[i].Rumble); iniFile.Set(SectionName, "RumbleStrength", WiiMoteEmu::WiiMapping[i].RumbleStrength); iniFile.Set(SectionName, "TriggerType", WiiMoteEmu::WiiMapping[i].TriggerType); + + // UDPWii + iniFile.Set(SectionName, "UDPWii_Enable", WiiMoteEmu::WiiMapping[i].UDPWM.enable); + iniFile.Set(SectionName, "UDPWii_Port", WiiMoteEmu::WiiMapping[i].UDPWM.port); + iniFile.Set(SectionName, "UDPWii_EnableAccel", WiiMoteEmu::WiiMapping[i].UDPWM.enableAccel); + iniFile.Set(SectionName, "UDPWii_EnableButtons", WiiMoteEmu::WiiMapping[i].UDPWM.enableButtons); + iniFile.Set(SectionName, "UDPWii_EnableIR", WiiMoteEmu::WiiMapping[i].UDPWM.enableIR); + iniFile.Set(SectionName, "UDPWii_EnableNunchuck", WiiMoteEmu::WiiMapping[i].UDPWM.enableNunchuck); } iniFile.Save((std::string(File::GetUserPath(D_CONFIG_IDX)) + "Wiimote.ini").c_str()); diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp index 6389e16a97..a871205227 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp @@ -45,6 +45,14 @@ BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog) EVT_CHECKBOX(IDC_WIIAUTORECONNECT, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHOICE(IDC_EXTCONNECTED, WiimoteBasicConfigDialog::GeneralSettingsChanged) + //UDPWii + EVT_CHECKBOX(IDC_UDPWIIENABLE, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + EVT_CHECKBOX(IDC_UDPWIIACCEL, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + EVT_CHECKBOX(IDC_UDPWIIBUTT, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + EVT_CHECKBOX(IDC_UDPWIIIR, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + EVT_CHECKBOX(IDC_UDPWIINUN, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + EVT_TEXT(IDT_UDPWIIPORT, WiimoteBasicConfigDialog::UDPWiiSettingsChanged) + // IR cursor EVT_COMMAND_SCROLL(IDS_WIDTH, WiimoteBasicConfigDialog::IRCursorChanged) EVT_COMMAND_SCROLL(IDS_HEIGHT, WiimoteBasicConfigDialog::IRCursorChanged) @@ -169,6 +177,22 @@ void WiimoteBasicConfigDialog::CreateGUIControls() m_WiiMotionPlusConnected[i]->Enable(false); m_Extension[i] = new wxChoice(m_Controller[i], IDC_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator); + + // UDPWii + m_UDPWiiEnable[i] = new wxCheckBox(m_Controller[i], IDC_UDPWIIENABLE, wxT("Enable UDPWii")); + m_UDPWiiEnable[i]->SetToolTip(wxT("Enable listening for wiimote data on the network. Requires emulation restart")); + m_UDPWiiAccel[i] = new wxCheckBox(m_Controller[i], IDC_UDPWIIACCEL, wxT("Update acceleration from UDPWii")); + m_UDPWiiAccel[i]->SetToolTip(wxT("Retrieve acceleration data from a device on the network")); + m_UDPWiiButt[i] = new wxCheckBox(m_Controller[i], IDC_UDPWIIBUTT, wxT("Update buttons from UDPWii")); + m_UDPWiiButt[i]->SetToolTip(wxT("Retrieve button data from a device on the network. This doesn't affect keyboard mappings")); + m_UDPWiiIR[i] = new wxCheckBox(m_Controller[i], IDC_UDPWIIIR, wxT("Update IR pointer from UDPWii")); + m_UDPWiiIR[i]->SetToolTip(wxT("Retrieve IR pointer from a device on the network. Disables using mouse as pointer")); + m_UDPWiiNun[i] = new wxCheckBox(m_Controller[i], IDC_UDPWIINUN, wxT("Update nunchuck from UDPWii")); + m_UDPWiiNun[i]->SetToolTip(wxT("Retrieve nunchuck data from a device on the network.")); + m_UDPWiiPort[i] = new wxTextCtrl(m_Controller[i], IDT_UDPWIIPORT); + m_UDPWiiPort[i]->SetMaxLength(9); + m_TextUDPWiiPort[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("UDP Port:")); + m_TextUDPWiiPort[i]->SetToolTip(wxT("The UDP port on witch UDPWii listens for this remote.")); m_PairUpRealWiimote[i] = new wxButton(m_Controller[i], IDB_PAIRUP_REAL, wxT("Pair Up Real Wiimotes")); m_PairUpRealWiimote[i]->SetToolTip(wxT("Press the Buttons 1 and 2 on your Wiimote.\nThis might take a few seconds.\nIt only works if you are using Microsoft Bluetooth stack.")); // Only working with MS BT Stack. @@ -216,6 +240,16 @@ void WiimoteBasicConfigDialog::CreateGUIControls() m_SizeExtensions[i]->Add(m_WiiMotionPlusConnected[i], 0, wxEXPAND | wxALL, 5); m_SizeExtensions[i]->Add(m_Extension[i], 0, wxEXPAND | wxALL, 5); + m_SizeUDPWii[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Emulated UDPWii")); + m_SizeUDPWii[i]->Add(m_UDPWiiEnable[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWiiPort[i]= new wxBoxSizer(wxHORIZONTAL); + m_SizeUDPWiiPort[i]->Add(m_TextUDPWiiPort[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWiiPort[i]->Add(m_UDPWiiPort[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWii[i]->Add(m_SizeUDPWiiPort[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWii[i]->Add(m_UDPWiiAccel[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWii[i]->Add(m_UDPWiiButt[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWii[i]->Add(m_UDPWiiIR[i], 0, wxEXPAND | wxALL,1); + m_SizeUDPWii[i]->Add(m_UDPWiiNun[i], 0, wxEXPAND | wxALL,1); m_SizeReal[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Real Wiimote")); m_SizeReal[i]->Add(m_PairUpRealWiimote[i], 0, wxEXPAND | wxALL, 5); @@ -255,6 +289,7 @@ void WiimoteBasicConfigDialog::CreateGUIControls() 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_SizeBasicGeneralLeft[i]->Add(m_SizeUDPWii[i], 0, wxEXPAND | (wxUP), 5); m_SizeBasicGeneralRight[i] = new wxBoxSizer(wxVERTICAL); m_SizeBasicGeneralRight[i]->Add(m_SizeReal[i], 0, wxEXPAND | (wxUP), 5); @@ -462,6 +497,32 @@ void WiimoteBasicConfigDialog::IRCursorChanged(wxScrollEvent& event) UpdateGUI(); } +void WiimoteBasicConfigDialog::UDPWiiSettingsChanged(wxCommandEvent &event) +{ + switch(event.GetId()) + { + case IDC_UDPWIIENABLE: + WiiMoteEmu::WiiMapping[m_Page].UDPWM.enable=m_UDPWiiEnable[m_Page]->GetValue(); + break; + case IDC_UDPWIIACCEL: + WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableAccel=m_UDPWiiAccel[m_Page]->GetValue(); + break; + case IDC_UDPWIIIR: + WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableIR=m_UDPWiiIR[m_Page]->GetValue(); + break; + case IDC_UDPWIIBUTT: + WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableButtons=m_UDPWiiButt[m_Page]->GetValue(); + break; + case IDC_UDPWIINUN: + WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableNunchuck=m_UDPWiiNun[m_Page]->GetValue(); + break; + case IDT_UDPWIIPORT: + strncpy(WiiMoteEmu::WiiMapping[m_Page].UDPWM.port,(const char*)(m_UDPWiiPort[m_Page]->GetValue().mb_str(wxConvUTF8)),10); + break; + } + UpdateGUI(); +} + void WiimoteBasicConfigDialog::UpdateGUI() { /* I have disabled this option during a running game because it's enough to be able to switch @@ -509,6 +570,16 @@ void WiimoteBasicConfigDialog::UpdateGUI() m_SliderTop[m_Page]->SetValue(g_Config.iIRTop); m_SliderIrLevel[m_Page]->SetValue(g_Config.iIRLevel); + //Update UDPWii + m_UDPWiiEnable[m_Page]->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY); + m_UDPWiiPort[m_Page]->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY); + m_UDPWiiEnable[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].UDPWM.enable); + m_UDPWiiAccel[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableAccel); + m_UDPWiiButt[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableButtons); + m_UDPWiiIR[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableIR); + m_UDPWiiNun[m_Page]->SetValue(WiiMoteEmu::WiiMapping[m_Page].UDPWM.enableNunchuck); + m_UDPWiiPort[m_Page]->ChangeValue(wxString::FromAscii(WiiMoteEmu::WiiMapping[m_Page].UDPWM.port)); + m_CheckAR43[m_Page]->SetValue(g_Config.bKeepAR43); m_CheckAR169[m_Page]->SetValue(g_Config.bKeepAR169); m_Crop[m_Page]->SetValue(g_Config.bCrop); diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h index 44ed22924a..6dbb3d329f 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h @@ -84,7 +84,12 @@ class WiimoteBasicConfigDialog : public wxDialog *m_CheckAR43[MAX_WIIMOTES], *m_CheckAR169[MAX_WIIMOTES], *m_Crop[MAX_WIIMOTES], - *m_WiiAutoReconnect[MAX_WIIMOTES]; + *m_WiiAutoReconnect[MAX_WIIMOTES], + *m_UDPWiiEnable[MAX_WIIMOTES], + *m_UDPWiiAccel[MAX_WIIMOTES], + *m_UDPWiiButt[MAX_WIIMOTES], + *m_UDPWiiIR[MAX_WIIMOTES], + *m_UDPWiiNun[MAX_WIIMOTES]; wxStaticText *m_TextScreenWidth[MAX_WIIMOTES], *m_TextScreenHeight[MAX_WIIMOTES], @@ -92,7 +97,8 @@ class WiimoteBasicConfigDialog : public wxDialog *m_TextScreenTop[MAX_WIIMOTES], *m_TextScreenIrLevel[MAX_WIIMOTES], *m_TextAR[MAX_WIIMOTES], - *m_TextFoundRealWiimote[MAX_WIIMOTES]; + *m_TextFoundRealWiimote[MAX_WIIMOTES], + *m_TextUDPWiiPort[MAX_WIIMOTES]; wxBoxSizer *m_MainSizer, *m_SizeBasicGeneral[MAX_WIIMOTES], @@ -101,13 +107,17 @@ class WiimoteBasicConfigDialog : public wxDialog *m_SizerIRPointerWidth[MAX_WIIMOTES], *m_SizerIRPointerHeight[MAX_WIIMOTES], *m_SizerIRPointerScreen[MAX_WIIMOTES], - *m_SizerIRPointerSensitivity[MAX_WIIMOTES]; + *m_SizerIRPointerSensitivity[MAX_WIIMOTES], + *m_SizeUDPWiiPort[MAX_WIIMOTES]; wxStaticBoxSizer *m_SizeBasic[MAX_WIIMOTES], *m_SizeEmu[MAX_WIIMOTES], *m_SizeReal[MAX_WIIMOTES], *m_SizeExtensions[MAX_WIIMOTES], - *m_SizerIRPointer[MAX_WIIMOTES]; + *m_SizerIRPointer[MAX_WIIMOTES], + *m_SizeUDPWii[MAX_WIIMOTES]; + + wxTextCtrl *m_UDPWiiPort[MAX_WIIMOTES]; enum { @@ -131,6 +141,14 @@ class WiimoteBasicConfigDialog : public wxDialog IDC_WIIAUTORECONNECT, IDC_EXTCONNECTED, + //UDPWii + IDC_UDPWIIENABLE, + IDC_UDPWIIACCEL, + IDC_UDPWIIBUTT, + IDC_UDPWIIIR, + IDC_UDPWIINUN, + IDT_UDPWIIPORT, + // Real IDB_PAIRUP_REAL, IDB_REFRESH_REAL, @@ -147,6 +165,7 @@ class WiimoteBasicConfigDialog : public wxDialog void NotebookPageChanged(wxNotebookEvent& event); void GeneralSettingsChanged(wxCommandEvent& event); void IRCursorChanged(wxScrollEvent& event); + void UDPWiiSettingsChanged(wxCommandEvent& event); void DoRefreshReal(); // Real void DoUseReal(); diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h index 9fa5ec8687..548cd17a50 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h @@ -33,6 +33,8 @@ #include "wiimote_hid.h" // Local #include "Encryption.h" +#include "UDPWiimote.h" + #if defined(HAVE_X11) && HAVE_X11 #include #endif @@ -276,6 +278,16 @@ struct SMotion STiltData TiltNC; }; +struct UDPWiiSettings +{ + bool enable; + bool enableAccel; + bool enableButtons; + bool enableIR; + bool enableNunchuck; + char port[10]; + UDPWiimote *instance; +}; struct CONTROLLER_MAPPING_WII // WII PAD MAPPING { @@ -302,6 +314,8 @@ struct CONTROLLER_MAPPING_WII // WII PAD MAPPING SStickMapping Stick; int Button[LAST_CONSTANT]; SMotion Motion; + + UDPWiiSettings UDPWM; }; // Gamepad input diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp index fba2df8a9e..c7cb786a93 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDynamics.cpp @@ -256,18 +256,22 @@ void TiltByKeyboard(STiltData &_TiltData, int Type) void TiltWiimote(int &_x, int &_y, int &_z) { // Select input method and return the x, y, x values - if (WiiMapping[g_ID].Tilt.InputWM == FROM_KEYBOARD) - TiltByKeyboard(WiiMapping[g_ID].Motion.TiltWM, 0); + if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableAccel)) + WiiMapping[g_ID].UDPWM.instance->getAccel(_x,_y,_z); else - TiltByGamepad(WiiMapping[g_ID].Motion.TiltWM, WiiMapping[g_ID].Tilt.InputWM); + { + if (WiiMapping[g_ID].Tilt.InputWM == FROM_KEYBOARD) + TiltByKeyboard(WiiMapping[g_ID].Motion.TiltWM, 0); + else + TiltByGamepad(WiiMapping[g_ID].Motion.TiltWM, WiiMapping[g_ID].Tilt.InputWM); - // Adjust angles, it's only needed if both roll and pitch is used together - if (WiiMapping[g_ID].Tilt.RollRange && WiiMapping[g_ID].Tilt.PitchRange) - AdjustAngles(WiiMapping[g_ID].Motion.TiltWM.Roll, WiiMapping[g_ID].Motion.TiltWM.Pitch); - - // Calculate the accelerometer value from this tilt angle - TiltToAccelerometer(_x, _y, _z,WiiMapping[g_ID].Motion.TiltWM); + // Adjust angles, it's only needed if both roll and pitch is used together + if (WiiMapping[g_ID].Tilt.RollRange && WiiMapping[g_ID].Tilt.PitchRange) + AdjustAngles(WiiMapping[g_ID].Motion.TiltWM.Roll, WiiMapping[g_ID].Motion.TiltWM.Pitch); + // Calculate the accelerometer value from this tilt angle + TiltToAccelerometer(_x, _y, _z,WiiMapping[g_ID].Motion.TiltWM); + } //DEBUG_LOG(WIIMOTE, "Roll:%i, Pitch:%i, _x:%u, _y:%u, _z:%u", g_Wiimote_kbd.TiltData.Roll, g_Wiimote_kbd.TiltData.Pitch, _x, _y, _z); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 37bb924874..875c0d1347 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -344,6 +344,13 @@ void Shutdown() if (SDL_WasInit(0)) SDL_Quit(); */ + + for (int i=0; iupdate(); + + if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableButtons)) + mask=WiiMapping[g_ID].UDPWM.instance->getButtons(); + // Allow both mouse buttons and keyboard to press a and b - _core.a = IsKey(EWM_A); - _core.b = IsKey(EWM_B); - _core.one = IsKey(EWM_ONE); - _core.two = IsKey(EWM_TWO); - _core.plus = IsKey(EWM_P); - _core.minus = IsKey(EWM_M); - _core.home = IsKey(EWM_H); + _core.a = IsKey(EWM_A)||(mask&UDPWM_BA); + _core.b = IsKey(EWM_B)||(mask&UDPWM_BB); + _core.one = IsKey(EWM_ONE)||(mask&UDPWM_B1); + _core.two = IsKey(EWM_TWO)||(mask&UDPWM_B2); + _core.plus = IsKey(EWM_P)||(mask&UDPWM_BP); + _core.minus = IsKey(EWM_M)||(mask&UDPWM_BM); + _core.home = IsKey(EWM_H)||(mask&UDPWM_BH); /* Sideways controls (for example for Wario Land) if the Wiimote is intended to be held sideways */ if(WiiMapping[g_ID].bSideways) { - _core.left = IsKey(EWM_D); - _core.up = IsKey(EWM_L); - _core.right = IsKey(EWM_U); - _core.down = IsKey(EWM_R); + _core.left = IsKey(EWM_D)||(mask&UDPWM_BL); + _core.up = IsKey(EWM_L)||(mask&UDPWM_BU); + _core.right = IsKey(EWM_U)||(mask&UDPWM_BR); + _core.down = IsKey(EWM_R)||(mask&UDPWM_BU); } else { - _core.left = IsKey(EWM_L); - _core.up = IsKey(EWM_U); - _core.right = IsKey(EWM_R); - _core.down = IsKey(EWM_D); + _core.left = IsKey(EWM_L)||(mask&UDPWM_BL); + _core.up = IsKey(EWM_U)||(mask&UDPWM_BU); + _core.right = IsKey(EWM_R)||(mask&UDPWM_BR); + _core.down = IsKey(EWM_D)||(mask&UDPWM_BD); } } @@ -435,7 +442,10 @@ void FillReportAcc(wm_accel& _acc) int acc_y = _acc.y; int acc_z = _acc.z; - if (IsKey(EWM_SHAKE) && !WiiMapping[g_ID].Motion.TiltWM.Shake) + if (((WiiMapping[g_ID].UDPWM.instance)&& + (WiiMapping[g_ID].UDPWM.enableButtons)&& + (WiiMapping[g_ID].UDPWM.instance->getButtons()&UDPWM_SK)) + ||(IsKey(EWM_SHAKE))&& !WiiMapping[g_ID].Motion.TiltWM.Shake) WiiMapping[g_ID].Motion.TiltWM.Shake = 1; // Step the shake simulation one step @@ -555,7 +565,10 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) memset(&_ir1, 0xff, sizeof(wm_ir_extended)); float MouseX, MouseY; - GetMousePos(MouseX, MouseY); + if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableIR)) + WiiMapping[g_ID].UDPWM.instance->getIR(MouseX,MouseY); + else + GetMousePos(MouseX, MouseY); // If we are outside the screen leave the values at 0xff if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return; @@ -633,7 +646,10 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) memset(&_ir1, 0xff, sizeof(wm_ir_basic)); float MouseX, MouseY; - GetMousePos(MouseX, MouseY); + if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableIR)) + WiiMapping[g_ID].UDPWM.instance->getIR(MouseX,MouseY); + else + GetMousePos(MouseX, MouseY); // If we are outside the screen leave the values at 0xff if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return; @@ -752,6 +768,29 @@ void FillReportExtension(wm_extension& _ext) _ext.ay = acc_y; _ext.az = acc_z; + if ((WiiMapping[g_ID].UDPWM.instance)&&(WiiMapping[g_ID].UDPWM.enableNunchuck)) + { + float x,y; + u8 b; + WiiMapping[g_ID].UDPWM.instance->getNunchuck(x,y,b); + //NOTICE_LOG(WIIMOTE,"%f %f %x",x,y,b); + //x + int factNeg= + g_nu.jx.center - g_nu.jx.min; + int factPoz= - g_nu.jx.center + g_nu.jx.max; + if (x==0) _ext.jx=g_nu.jx.center; + if (x>0) _ext.jx=(int)(x*factPoz+g_nu.jx.center); + if (x<0) _ext.jx=(int)(x*factNeg+g_nu.jx.center); + //y + factNeg= + g_nu.jy.center - g_nu.jy.min; + factPoz= - g_nu.jy.center + g_nu.jy.max; + if (y==0) _ext.jy=g_nu.jy.center; + if (y>0) _ext.jy=(int)(y*factPoz+g_nu.jy.center); + if (y<0) _ext.jy=(int)(y*factNeg+g_nu.jy.center); + //buttons + if(IsKey(ENC_C)||(b&UDPWM_NC)) _ext.bt &= ~0x02; + if(IsKey(ENC_Z)||(b&UDPWM_NZ)) _ext.bt &= ~0x01; + } else + { // Update the analog stick if (WiiMapping[g_ID].Stick.NC == FROM_KEYBOARD) { @@ -835,6 +874,7 @@ void FillReportExtension(wm_extension& _ext) if(IsKey(ENC_C)) _ext.bt &= ~0x02; if(IsKey(ENC_Z)) _ext.bt &= ~0x01; + } } /* Here we encrypt the report */ diff --git a/Source/Plugins/Plugin_Wiimote/Src/SConscript b/Source/Plugins/Plugin_Wiimote/Src/SConscript index ec482e0df4..49664cf3be 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/SConscript +++ b/Source/Plugins/Plugin_Wiimote/Src/SConscript @@ -17,6 +17,7 @@ files = [ "Encryption.cpp", "main.cpp", "Rumble.cpp", + "UDPWiimote.cpp" ] if wmenv['HAVE_WX']: files += [ diff --git a/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.cpp b/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.cpp new file mode 100644 index 0000000000..c7fef02fc1 --- /dev/null +++ b/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.cpp @@ -0,0 +1,222 @@ +#include "UDPWiimote.h" + +#ifdef _WIN32 + +#include +#include + +#define sock_t SOCKET +#define ERRNO WSAGetLastError() +#define EWOULDBLOCK WSAEWOULDBLOCK +#define BAD_SOCK INVALID_SOCKET +#define close(x) closesocket(x) +#define cleanup do {noinst--; if (noinst==0) WSACleanup();} while (0) +#define blockingoff(sock) ioctlsocket(sock, FIONBIO, &iMode) +#define dataz char* +#ifdef _MSC_VER +#pragma comment (lib, "Ws2_32.lib") +#endif + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BAD_SOCK -1 +#define ERRNO errno +#define cleanup noinst-- +#define blockingoff(sock) fcntl(sock, F_SETFL, O_NONBLOCK) +#define dataz void* +#define sock_t int + +#endif + +#include "EmuMain.h" +#include +#include + +struct UDPWiimote::_d +{ + sock_t sockfd; +}; + +int UDPWiimote::noinst=0; + +UDPWiimote::UDPWiimote(const char *port) : d(new _d) ,x(0),y(0),z(0),nunX(0),nunY(0),mask(0),nunMask(0),pointerX(-0.1),pointerY(-0.1) +{ + #ifdef _WIN32 + u_long iMode = 1; + #endif + struct addrinfo hints, *servinfo, *p; + int rv; + + #ifdef _WIN32 + if (noinst==0) + { + WORD sockVersion; + WSADATA wsaData; + sockVersion = MAKEWORD(2, 2); + WSAStartup(sockVersion, &wsaData); + } + #endif + + noinst++; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) { +// fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + cleanup; + this->err=-1; + return; + } + + // loop through all the results and bind to the first we can + for(p = servinfo; p != NULL; p = p->ai_next) { + if (((d->sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)),d->sockfd) == BAD_SOCK) { + continue; + } + + if (bind(d->sockfd, p->ai_addr, p->ai_addrlen) == -1) { + close(d->sockfd); + continue; + } + + break; + } + + if (p == NULL) { + cleanup; + this->err=-2; + return; + } + + freeaddrinfo(servinfo); + blockingoff(d->sockfd); + this->err=0; + return; +} + +UDPWiimote::~UDPWiimote() +{ + close(d->sockfd); + cleanup; + delete d; +} + +int UDPWiimote::readPack(void * data, int *size) +{ + int numbytes; + size_t addr_len; + struct sockaddr_storage their_addr; + addr_len = sizeof their_addr; + if ((numbytes = recvfrom(d->sockfd, (dataz)data, (*size) , 0, + (struct sockaddr *)&their_addr, (socklen_t*)&addr_len)) == -1) { + if (ERRNO==EWOULDBLOCK) + return -1; + return -2; + } else + (*size)=numbytes; + return 0; +} + +#define ACCEL_FLAG (1<<0) +#define BUTT_FLAG (1<<1) +#define IR_FLAG (1<<2) +#define NUN_FLAG (1<<3) + +void UDPWiimote::update() +{ + u8 bf[64]; + int size=60; + int res=0; + u8 time=0; + int nopack=0; + for (int i=0; (res=readPack(&bf,&size)),(i<100)&&(res!=-1); (res<-1)?i++:0) + { + if (res==0) + { + if (bf[0]==0xde) + { + if (bf[1]==0) + time=0; + if (bf[1]>=time) //packet timestamp. assures order is maintained + { + nopack++; + time=bf[1]; + u32 *p=(u32*)(&bf[3]); + if (bf[2]&ACCEL_FLAG) + { + double ux,uy,uz; + ux=(double)((s32)ntohl(*p)); p++; + uy=(double)((s32)ntohl(*p)); p++; + uz=(double)((s32)ntohl(*p)); p++; + this->x=ux/1048576; //packet accel data + this->y=uy/1048576; + this->z=uz/1048576; + } + if (bf[2]&BUTT_FLAG) + { + mask=ntohl(*p); p++; + } + if (bf[2]&IR_FLAG) + { + this->pointerX=((double)((s32)ntohl(*p)))/1048576; p++; + this->pointerY=((double)((s32)ntohl(*p)))/1048576; p++; + } + if (bf[2]&NUN_FLAG) + { + this->nunMask=*((u8*)p); p=(u32*)(((u8*)p)+1); + this->nunX=((double)((s32)ntohl(*p)))/1048576; p++; + this->nunY=((double)((s32)ntohl(*p)))/1048576; p++; + } + } + } + } + if (res==-2) + { + ERROR_LOG(WIIMOTE,"UDPWii Packet error"); + } + } + //NOTICE_LOG(WIIMOTE,"UDPWii update result:np:%d x:%f y:%f z:%f nx:%f ny:%f px:%f py:%f bmask:%x nmask:%x", + // nopack,this->x,this->y,this->z,this->nunX, this->nunY,this->pointerX,this->pointerY, this->mask, this->nunMask); +} + +void UDPWiimote::getAccel(int &x, int &y, int &z) +{ + //NOTICE_LOG(WIIMOTE,"%lf %lf %lf",this->x, this-y, this->z); + float xg = WiiMoteEmu::g_wm.cal_g.x; + float yg = WiiMoteEmu::g_wm.cal_g.y; + float zg = WiiMoteEmu::g_wm.cal_g.z; + x = WiiMoteEmu::g_wm.cal_zero.x + (int)(xg * this->x); + y = WiiMoteEmu::g_wm.cal_zero.y + (int)(yg * this->y); + z = WiiMoteEmu::g_wm.cal_zero.z + (int)(zg * this->z); +} + +u32 UDPWiimote::getButtons() +{ + return mask; +} + +void UDPWiimote::getIR(float &x, float &y) +{ + x=(float)this->pointerX; + y=(float)this->pointerY; +} + +void UDPWiimote::getNunchuck(float &x, float &y, u8 &mask) +{ + x=(float)this->nunX; + y=(float)this->nunY; + mask=this->nunMask; +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.h b/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.h new file mode 100644 index 0000000000..476860ba47 --- /dev/null +++ b/Source/Plugins/Plugin_Wiimote/Src/UDPWiimote.h @@ -0,0 +1,44 @@ +#ifndef UDPWIIMOTE_H +#define UDPWIIMOTE_H + +#include "Common.h" + +#define UDPWM_B1 (1<<0) +#define UDPWM_B2 (1<<1) +#define UDPWM_BA (1<<2) +#define UDPWM_BB (1<<3) +#define UDPWM_BP (1<<4) +#define UDPWM_BM (1<<5) +#define UDPWM_BH (1<<6) +#define UDPWM_BU (1<<7) +#define UDPWM_BD (1<<8) +#define UDPWM_BL (1<<9) +#define UDPWM_BR (1<<10) +#define UDPWM_SK (1<<11) +#define UDPWM_NC (1<<0) +#define UDPWM_NZ (1<<1) + +class UDPWiimote +{ +public: + UDPWiimote(const char * port); + virtual ~UDPWiimote(); + void update(); + void getAccel(int &x, int &y, int &z); + u32 getButtons(); + void getNunchuck(float &x, float &y, u8 &mask); + void getIR(float &x, float &y); + int getErrNo() {return err;}; +private: + int readPack(void * data, int *size); + struct _d; //using pimpl because SOCKET on windows is defined in Winsock2.h, witch doesen't have include guards + _d *d; + double x,y,z; + double nunX,nunY; + double pointerX,pointerY; + u8 nunMask; + u32 mask; + int err; + static int noinst; +}; +#endif \ No newline at end of file