From 220eafad0e2431b114a3fbe8574b5bf7e34f4e1c Mon Sep 17 00:00:00 2001 From: John Peterson Date: Tue, 3 Feb 2009 00:59:26 +0000 Subject: [PATCH] Wiimote: The first working IR recording, use Alt + the numerical HotKey to play back the IR data associated with a recording git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2078 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/StringUtil.cpp | 5 +- Source/Core/Common/Src/StringUtil.h | 2 +- .../Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp | 67 ++++-- Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h | 9 +- .../Plugin_Wiimote/Src/DataReports.cpp | 4 +- .../Plugin_Wiimote/Src/EmuDefinitions.h | 10 +- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 86 +++++--- .../Plugins/Plugin_Wiimote/Src/FillReport.cpp | 204 +++++++++++++----- .../Plugin_Wiimote/Src/ReadWiimote.cpp | 123 ++++++----- Source/Plugins/Plugin_Wiimote/Src/main.h | 5 + .../Plugins/Plugin_Wiimote/Src/wiimote_hid.h | 2 +- .../Plugin_Wiimote/Src/wiimote_real.cpp | 2 + .../Plugins/Plugin_Wiimote/Src/wiimote_real.h | 2 + 13 files changed, 360 insertions(+), 161 deletions(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 28cb67d08b..ef95259bd0 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -149,14 +149,15 @@ std::string StringFromFormat(const char* format, ...) // =================================================== /* For Debugging. Read out an u8 array. */ // ---------------- -std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len) +std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len, bool Spaces) { //const u8* _data = (const u8*)data; std::string Temp; for (u32 i = 0; i < size; i++) { char Buffer[128]; - sprintf(Buffer, "%02x ", data[i + offset]); + if (Spaces) sprintf(Buffer, "%02x ", data[i + offset]); + else sprintf(Buffer, "%02x", data[i + offset]); if((i + 1) % line_len == 0) Temp.append("\n"); // break long lines Temp.append(Buffer); } diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h index 5604fd64db..244f57c45f 100644 --- a/Source/Core/Common/Src/StringUtil.h +++ b/Source/Core/Common/Src/StringUtil.h @@ -34,7 +34,7 @@ void StringFromFormatV(std::string* out, const char* format, va_list args); bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args); // Good -std::string ArrayToString(const u8 *data, u32 size, u32 offset = 0, int line_len = 20); +std::string ArrayToString(const u8 *data, u32 size, u32 offset = 0, int line_len = 20, bool Spaces = true); template diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp index b79799e70a..3bb8c945e2 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp @@ -192,6 +192,10 @@ void ConfigDialog::LoadFile() std::string TmpGameName; file.Get(SaveName.c_str(), "GameName", &TmpGameName, ""); m_RecordGameText[i]->SetValue(wxString::FromAscii(TmpGameName.c_str())); + // IR Bytes + std::string TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, ""); + m_RecordIRBytesText[i]->SetValue(wxString::FromAscii(TmpIRBytes.c_str())); + // Recording speed int TmpRecordSpeed; file.Get(SaveName.c_str(), "RecordingSpeed", &TmpRecordSpeed, -1); if(TmpRecordSpeed != -1) @@ -343,6 +347,7 @@ void ConfigDialog::CreateGUIControls() wxStaticBoxSizer * sbRealRoll = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("Roll and Pitch")); wxStaticBoxSizer * sbRealGForce = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("G-Force")); wxStaticBoxSizer * sbRealAccel = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("Accelerometer")); + wxStaticBoxSizer * sbRealIR = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("IR")); // Width and height of the gauges static const int Gw = 35, Gh = 130; @@ -357,6 +362,12 @@ void ConfigDialog::CreateGUIControls() m_GaugeAccel[1] = new wxGauge( m_PageReal, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); m_GaugeAccel[2] = new wxGauge( m_PageReal, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + // The text controls + m_TextIR = new wxStaticText(m_PageReal, wxID_ANY, wxT("Cursor: 000 000\nDistance: 0000")); + + // ----------------------------- + // The sizers for all gauges together with their label + // ----------- wxBoxSizer * sBoxBattery = new wxBoxSizer(wxVERTICAL); wxBoxSizer * sBoxRoll[2]; sBoxRoll[0] = new wxBoxSizer(wxVERTICAL); @@ -377,7 +388,11 @@ void ConfigDialog::CreateGUIControls() m_TextX[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextX[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextY[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextY[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextZ[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextZ[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + // ---------------- + // ----------------------------- + // Set up sizers + // ----------- sBoxBattery->Add(m_GaugeBattery, 0, wxEXPAND | (wxALL), 5); sBoxBattery->Add(m_TextBattery, 0, wxEXPAND | (wxALL), 0); sBoxRoll[0]->Add(m_GaugeRoll[0], 0, wxEXPAND | (wxALL), 5); sBoxRoll[0]->Add(m_TextRoll, 0, wxEXPAND | (wxALL), 0); @@ -395,12 +410,16 @@ void ConfigDialog::CreateGUIControls() sbRealRoll->Add(sBoxRoll[0], 0, wxEXPAND | (wxALL), 5); sbRealRoll->Add(sBoxRoll[1], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[0], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[1], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[2], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[0], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[1], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[2], 0, wxEXPAND | (wxALL), 5); - + sbRealIR->Add(m_TextIR, 0, wxEXPAND | (wxALL), 5); + sbRealWiimoteStatus->Add(sbRealBattery, 0, wxEXPAND | (wxLEFT), 0); sbRealWiimoteStatus->Add(sbRealRoll, 0, wxEXPAND | (wxLEFT), 5); sbRealWiimoteStatus->Add(sbRealGForce, 0, wxEXPAND | (wxLEFT), 5); sbRealWiimoteStatus->Add(sbRealAccel, 0, wxEXPAND | (wxLEFT), 5); + sbRealWiimoteStatus->Add(sbRealIR, 0, wxEXPAND | (wxLEFT), 5); + // ---------------- + // Tool tips m_GaugeBattery->SetToolTip(wxT("Press '+' to show the current status. Press '-' to stop recording the status.")); // ========================================== @@ -423,7 +442,8 @@ void ConfigDialog::CreateGUIControls() wxStaticText * m_TextHotKey = new wxStaticText(m_PageReal, wxID_ANY, wxT("HotKey"), wxDefaultPosition, wxSize(40, 15), wxALIGN_CENTRE); wxStaticText * m_TextMovement = new wxStaticText(m_PageReal, wxID_ANY, wxT("Movement name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE); wxStaticText * m_TextGame = new wxStaticText(m_PageReal, wxID_ANY, wxT("Game name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE); - wxStaticText * m_TextRecSped = new wxStaticText(m_PageReal, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(30, 15), wxALIGN_CENTRE); + wxStaticText * m_TextIRBytes = new wxStaticText(m_PageReal, wxID_ANY, wxT("IR"), wxDefaultPosition, wxSize(20, 15), wxALIGN_CENTRE); + wxStaticText * m_TextRecSped = new wxStaticText(m_PageReal, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(33, 15), wxALIGN_CENTRE); wxStaticText * m_TextPlaySpeed = new wxStaticText(m_PageReal, wxID_ANY, wxT("Pl. s."), wxDefaultPosition, wxSize(40, 15), wxALIGN_CENTRE); m_TextRec->SetToolTip(wxT( "To record a movement first press this button, then start the recording by pressing 'A' on the Wiimote and stop the recording\n" @@ -444,6 +464,7 @@ void ConfigDialog::CreateGUIControls() sRealRecord[0]->Add(m_TextHotKey, 0, wxEXPAND | (wxLEFT), 5); sRealRecord[0]->Add(m_TextMovement, 0, wxEXPAND | (wxLEFT), 5); sRealRecord[0]->Add(m_TextGame, 0, wxEXPAND | (wxLEFT), 5); + sRealRecord[0]->Add(m_TextIRBytes, 0, wxEXPAND | (wxLEFT), 5); sRealRecord[0]->Add(m_TextRecSped, 0, wxEXPAND | (wxLEFT), 5); sRealRecord[0]->Add(m_TextPlaySpeed, 0, wxEXPAND | (wxLEFT), 5); sbRealRecord->Add(sRealRecord[0], 0, wxEXPAND | (wxALL), 0); @@ -455,17 +476,20 @@ void ConfigDialog::CreateGUIControls() m_RecordHotKey[i] = new wxChoice(m_PageReal, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey); m_RecordText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_TEXT, wxT(""), wxDefaultPosition, wxSize(200, 19)); m_RecordGameText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_GAMETEXT, wxT(""), wxDefaultPosition, wxSize(200, 19)); + m_RecordIRBytesText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_IRBYTESTEXT, wxT(""), wxDefaultPosition, wxSize(25, 19)); m_RecordSpeed[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_SPEED, wxT(""), wxDefaultPosition, wxSize(30, 19), wxTE_READONLY | wxTE_CENTRE); m_RecordPlayBackSpeed[i] = new wxChoice(m_PageReal, IDT_RECORD_PLAYSPEED, wxDefaultPosition, wxDefaultSize, StrPlayBackSpeed); m_RecordText[i]->SetMaxLength(35); m_RecordGameText[i]->SetMaxLength(35); + m_RecordIRBytesText[i]->Enable(false); m_RecordSpeed[i]->Enable(false); sRealRecord[i]->Add(m_RecordButton[i], 0, wxEXPAND | (wxLEFT), 5); sRealRecord[i]->Add(m_RecordHotKey[i], 0, wxEXPAND | (wxLEFT), 5); sRealRecord[i]->Add(m_RecordText[i], 0, wxEXPAND | (wxLEFT), 5); sRealRecord[i]->Add(m_RecordGameText[i], 0, wxEXPAND | (wxLEFT), 5); + sRealRecord[i]->Add(m_RecordIRBytesText[i], 0, wxEXPAND | (wxLEFT), 5); sRealRecord[i]->Add(m_RecordSpeed[i], 0, wxEXPAND | (wxLEFT), 5); sRealRecord[i]->Add(m_RecordPlayBackSpeed[i], 0, wxEXPAND | (wxLEFT), 5); @@ -519,7 +543,7 @@ void ConfigDialog::ConvertToString() // Load ini file IniFile file; file.Load("WiimoteMovement.ini"); - std::string TmpStr = "", TmpTime = ""; + std::string TmpStr = "", TmpIR = "", TmpTime = ""; for (int i = 0; i < m_vRecording.size(); i++) { @@ -529,19 +553,23 @@ void ConfigDialog::ConvertToString() TmpStr += StringFromFormat("%02x", m_vRecording.at(i).z); if(i < (m_vRecording.size() - 1)) TmpStr += ","; - /* Break just short of the IniFile.cpp byte limit so that we don't crash file.Load() the next time. - This limit should never be hit because of the recording limit below. I keep it here just in case. */ - if(TmpStr.length() > (1024*10 - 10)) - { - break; - PanicAlert("Your recording was to long, the entire recording was not saved."); - } + // Write the IR data + TmpIR += ArrayToString(m_vRecording.at(i).IR, IRBytes, 0, 30, false); + if(i < (m_vRecording.size() - 1)) TmpIR += ","; // Write the timestamps. The upper limit is 99 seconds. int Time = (int)((m_vRecording.at(i).Time - m_vRecording.at(0).Time) * 1000); TmpTime += StringFromFormat("%05i", Time); if(i < (m_vRecording.size() - 1)) TmpTime += ","; //Console::Print("Time: %f %i\n", m_vRecording.at(i).Time, Time); + + /* Break just short of the IniFile.cpp byte limit so that we don't crash file.Load() the next time. + This limit should never be hit because of the recording limit below. I keep it here just in case. */ + if(TmpStr.length() > (1024*10 - 10) || TmpIR.length() > (1024*10 - 10) || TmpTime.length() > (1024*10 - 10)) + { + break; + PanicAlert("Your recording was to long, the entire recording was not saved."); + } } // Recordings per second @@ -553,12 +581,15 @@ void ConfigDialog::ConvertToString() if (Time == 0 || m_vRecording.size() == 0) Rate = 0; // Update GUI + m_RecordIRBytesText[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), IRBytes)); m_RecordSpeed[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), Rate)); // Save file std::string SaveName = StringFromFormat("Recording%i", m_iRecordTo); file.Set(SaveName.c_str(), "Movement", TmpStr.c_str()); + file.Set(SaveName.c_str(), "IR", TmpIR.c_str()); file.Set(SaveName.c_str(), "Time", TmpTime.c_str()); + file.Set(SaveName.c_str(), "IRBytes", IRBytes); file.Set(SaveName.c_str(), "RecordingSpeed", Rate); // Set a default playback speed if none is set already @@ -651,8 +682,11 @@ void ConfigDialog::DoRecordA(bool Pressed) UpdateGUI(); } -void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z) +void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int _IRBytes) { + //std::string Tmp1 = ArrayToString(_IR, 20, 0, 30); + //Console::Print("DoRecordMovement: %s\n", Tmp1.c_str()); + if (!m_bRecording) return; //Console::Print("DoRecordMovement\n"); @@ -662,8 +696,12 @@ void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z) Tmp.y = _y; Tmp.z = _z; Tmp.Time = GetDoubleTime(); + memcpy(Tmp.IR, _IR, _IRBytes); m_vRecording.push_back(Tmp); + // Save the number of IR bytes + IRBytes = _IRBytes; + /* The upper limit of a recording coincides with the IniFile.cpp limit, each list element is 7 bytes, therefore be divide by 7 */ if (m_vRecording.size() > (10*1024 / 7 - 2) ) @@ -834,8 +872,8 @@ void ConfigDialog::UpdateGUI() unplugged and reinserted extensions. */ m_NunchuckConnected->SetValue(g_Config.bNunchuckConnected); m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected); - m_NunchuckConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote)); - m_ClassicControllerConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote)); + m_NunchuckConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning)); + m_ClassicControllerConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning)); /* I have disabled this option during a running game because it's enough to be able to switch between using and not using then. To also use the connect option during a running game would @@ -845,9 +883,6 @@ void ConfigDialog::UpdateGUI() m_ConnectRealWiimote->Enable(!g_EmulatorRunning); m_UseRealWiimote->Enable(g_RealWiiMotePresent && g_Config.bConnectRealWiimote); - - - // Linux has no FindItem() #ifdef _WIN32 for(int i = IDB_RECORD + 1; i < (IDB_RECORD + RECORDING_ROWS + 1); i++) diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h index ae32e3fdf1..23191b5680 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h @@ -48,15 +48,16 @@ class ConfigDialog : public wxDialog void OnKeyDown(wxKeyEvent& event); void LoadFile(); void SaveFile(); - // Status + // General status wxStaticText * m_TextUpdateRate; // Wiimote status wxGauge *m_GaugeBattery, *m_GaugeRoll[2], *m_GaugeGForce[3], *m_GaugeAccel[3]; + wxStaticText * m_TextIR; bool m_bWaitForRecording, m_bRecording, m_bAllowA; int m_iRecordTo; void RecordMovement(wxCommandEvent& event); - void DoRecordMovement(u8 _x, u8 _y, u8 _z); + void DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int IRBytes); void DoRecordA(bool Pressed); void ConvertToString(); wxTimer *m_TimeoutTimer, *m_TimeoutATimer; @@ -83,6 +84,7 @@ class ConfigDialog : public wxDialog wxChoice * m_RecordHotKey[RECORDING_ROWS + 1]; wxTextCtrl * m_RecordText[RECORDING_ROWS + 1]; wxTextCtrl * m_RecordGameText[RECORDING_ROWS + 1]; + wxTextCtrl * m_RecordIRBytesText[RECORDING_ROWS + 1]; wxTextCtrl * m_RecordSpeed[RECORDING_ROWS + 1]; wxChoice * m_RecordPlayBackSpeed[RECORDING_ROWS + 1]; @@ -96,6 +98,7 @@ class ConfigDialog : public wxDialog }; */ std::vector m_vRecording; + int IRBytes; enum { @@ -116,7 +119,7 @@ class ConfigDialog : public wxDialog ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS, IDB_RECORD = 2000, IDC_RECORD = 3000, - IDT_RECORD_TEXT, IDT_RECORD_GAMETEXT, IDT_RECORD_SPEED, IDT_RECORD_PLAYSPEED + IDT_RECORD_TEXT, IDT_RECORD_GAMETEXT, IDT_RECORD_IRBYTESTEXT, IDT_RECORD_SPEED, IDT_RECORD_PLAYSPEED }; void OnClose(wxCloseEvent& event); diff --git a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp index 495e6b1158..9993ce5307 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/DataReports.cpp @@ -185,8 +185,10 @@ void SendReportCoreAccelIr12(u16 _channelID) { FillReportInfo(pReport->c); FillReportAcc(pReport->a); - // We settle with emulating two objects, not all four. We leave object 2 and 3 with zero. + // We settle with emulating two objects, not all four. We leave object 2 and 3 with 0xff. FillReportIR(pReport->ir[0], pReport->ir[1]); + memset(&pReport->ir[2], 0xff, sizeof(wm_ir_extended)); + memset(&pReport->ir[3], 0xff, sizeof(wm_ir_extended)); LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr12()"); LOGV(WII_IPC_WIIMOTE, 2, " Offset: %08x", Offset); diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h index 99a7b06595..9825ac89ff 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuDefinitions.h @@ -56,11 +56,11 @@ namespace WiiMoteEmu #define wSENSOR_BAR_RADIUS 200 // Movement recording -extern int g_RecordingPlaying[2]; -extern int g_RecordingCounter[2]; -extern int g_RecordingPoint[2]; -extern double g_RecordingStart[2]; -extern double g_RecordingCurrentTime[2]; +extern int g_RecordingPlaying[3]; +extern int g_RecordingCounter[3]; +extern int g_RecordingPoint[3]; +extern double g_RecordingStart[3]; +extern double g_RecordingCurrentTime[3]; // Registry sizes #define WIIMOTE_EEPROM_SIZE (16*1024) diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 350c9becde..20b5685222 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -126,17 +126,27 @@ void LoadRecordedMovements() for(int i = 0; i < RECORDING_ROWS; i++) { + // Logging + Console::Print("Recording%i ", i + 1); + // Get row name std::string SaveName = StringFromFormat("Recording%i", i + 1); // Get movement std::string TmpMovement; file.Get(SaveName.c_str(), "Movement", &TmpMovement, ""); + // Get IR + std::string TmpIR; file.Get(SaveName.c_str(), "IR", &TmpIR, ""); + // Get time std::string TmpTime; file.Get(SaveName.c_str(), "Time", &TmpTime, ""); + // Get IR bytes + int TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, 0); + VRecording.at(i).IRBytes = TmpIRBytes; + SRecording Tmp; - for (int j = 0, k = 0; j < TmpMovement.length(); j+=7) + for (int j = 0, k = 0, l = 0; j < TmpMovement.length(); j+=7) { // Skip blank savings if (TmpMovement.length() < 3) continue; @@ -152,26 +162,62 @@ void LoadRecordedMovements() Tmp.y = (u8)TmpY; Tmp.z = (u8)TmpZ; - // Go to next set of time values - double Time = (double)atoi(TmpTime.substr(k, 5).c_str()); - Tmp.Time = (double)(Time/1000); - VRecording.at(i).Recording.push_back(Tmp); - k += 6; + // --------------------------------- + // Go to next set of IR values + // --------- + // If there is no IR data saving we fill the array with zeroes. This should only be able to occur from manual ini editing + // but we check for it anyway + if (TmpIRBytes == 0) for(int i = 0; i < 12; i++) Tmp.IR[i] = 0; + for(int ii = 0; ii < TmpIRBytes; ii++) + { + if(TmpIR.length() < (k + i + TmpIRBytes)) continue; // Safety check + std::string TmpStr = TmpIR.substr(k + ii*2, 2); + u32 TmpU32; + AsciiToHex(TmpStr.c_str(), TmpU32); + Tmp.IR[ii] = (u8)TmpU32; + } + if (TmpIRBytes == 10) k += (10*2 + 1); else k += (12*2 + 1); + // --------------------- + // Go to next set of time values + double Time = (double)atoi(TmpTime.substr(l, 5).c_str()); + Tmp.Time = (double)(Time/1000); + l += 6; + + // Save the values + VRecording.at(i).Recording.push_back(Tmp); + + // --------------------------------- + // 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"); } - // HotKey + // Get HotKey int TmpRecordHotKey; file.Get(SaveName.c_str(), "HotKey", &TmpRecordHotKey, -1); VRecording.at(i).HotKey = TmpRecordHotKey; - // Recording speed + // Get Recording speed int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1); VRecording.at(i).PlaybackSpeed = TmpPlaybackSpeed; - Console::Print("Size:%i HotKey:%i Speed:%i\n", - VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed + // --------------------------------- + // Logging + // --------- + std::string TmpIRLog; + if(TmpIRBytes > 0) + TmpIRLog = ArrayToString(VRecording.at(i).Recording.at(0).IR, TmpIRBytes, 0, 30); + else + TmpIRLog = ""; + + Console::Print("Size:%i HotKey:%i Speed:%i IR: %s\n", + VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed, + TmpIRLog.c_str() ); + // --------------------- } } // ================ @@ -331,22 +377,10 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size) for now I'm delaying all inputs. Both for status changes and Eeprom and registry reads and writes. */ - // Limit the delay to certain registry reads and writes - //if((data[1] == WM_WRITE_DATA || data[1] == WM_READ_DATA) - // && data[3] == 0xa4) - //{ - // There are no 0x22 replys to these report from the real wiimote - if(!(data[1] == WM_READ_DATA && data[2] == 0x00) - && !(data[1] == WM_REQUEST_STATUS) - ) - if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel); - //} - //else - //{ - //wm_write_data *wd = (wm_write_data*)sr->data; - //u32 address = convert24bit(wd->address); - //WmSendAck(_channelID, sr->channel, address); - //} + // 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 + if(!(data[1] == WM_READ_DATA && data[2] == 0x00) && !(data[1] == WM_REQUEST_STATUS)) + if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel); } break; diff --git a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp index c360e38b08..db1935291d 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/FillReport.cpp @@ -43,28 +43,29 @@ namespace WiiMoteEmu { -//****************************************************************************** +//************************************************************************************** // Recorded movements -//****************************************************************************** +//************************************************************************************** // ------------------------------------------ // Variables: 0 = Wiimote, 1 = Nunchuck // ---------------- -int g_RecordingPlaying[2]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1; -int g_RecordingCounter[2]; //g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0; -int g_RecordingPoint[2]; //g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0; -double g_RecordingStart[2]; //g_RecordingStart[0] = 0; g_RecordingStart[1] = 0; -double g_RecordingCurrentTime[2]; //g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0; +int g_RecordingPlaying[3]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1; +int g_RecordingCounter[3]; //g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0; +int g_RecordingPoint[3]; //g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0; +double g_RecordingStart[3]; //g_RecordingStart[0] = 0; g_RecordingStart[1] = 0; +double g_RecordingCurrentTime[3]; //g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0; // -------------------------- -void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm) +template +bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm) { // Return if the list is empty if(VRecording.at(g_RecordingPlaying[Wm]).Recording.size() == 0) { g_RecordingPlaying[Wm] = -1; Console::Print("Empty\n\n"); - return; + return false; } // Return if the playback speed is unset @@ -72,7 +73,22 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm) { Console::Print("PlaybackSpeed empty: %i\n\n", g_RecordingPlaying[Wm]); g_RecordingPlaying[Wm] = -1; - return; + return false; + } + + // Get IR bytes + int IRBytes = VRecording.at(g_RecordingPlaying[Wm]).IRBytes; + + // Return if the IR mode is wrong + if (Wm == WM_RECORDING_IR + && ( (IRBytes == 12 && !(g_ReportingMode == 0x33)) + || (IRBytes == 10 && !(g_ReportingMode == 0x36 || g_ReportingMode == 0x37)) + ) + ) + { + Console::Print("Wrong IR mode: %i\n\n", g_RecordingPlaying[Wm]); + g_RecordingPlaying[Wm] = -1; + return false; } // Get starting time @@ -106,13 +122,14 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm) g_RecordingStart[Wm] = 0; g_RecordingCurrentTime[Wm] = 0; Console::Print("End\n\n"); - return; + return false; } // Update values _x = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).x; _y = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).y; _z = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).z; + if(Wm == WM_RECORDING_IR) memcpy(&_IR, VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).IR, IRBytes); /**/ if (g_DebugAccelerometer) @@ -124,25 +141,53 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm) ); Console::Print("Accel x, y, z: %03u %03u %03u\n\n", _x, _y, _z); } - g_RecordingCounter[Wm]++; + + return true; +} +/* Because the playback is neatly controlled by RecordingPlayAccIR() we use these functions to be able to + use RecordingPlayAccIR() for both accelerometer and IR recordings */ +bool RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm) +{ + wm_ir_basic IR; + return RecordingPlayAccIR(_x, _y, _z, IR, Wm); +} +template +bool RecordingPlayIR(IRReportType &_IR) +{ + u8 x, y, z; + return RecordingPlayAccIR(x, y, z, _IR, 2); } -// Check if we should play a recording -int RecordingCheckKeys(bool Wiimote) +// Check if we should start the playback of a recording. Once it has been started it can not currently +// be stopped, it will always run to the end of the recording. +int RecordingCheckKeys(int Wiimote) { #ifdef _WIN32 - //Console::Print("RecordingCheckKeys\n"); + //Console::Print("RecordingCheckKeys: %i\n", Wiimote); - // Return if we don't have both a Shift and Ctrl + // ------------------------------------ + // Don't allow multiple action keys + // -------------- + // Return if we have both a Shift, Ctrl, and Alt + if ( GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU) ) return -1; + // Return if we have both a Shift and Ctrl if ( (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL)) ) return -1; + // Return if we have both a Ctrl and Alt + if ( (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU)) ) return -1; + // Return if we have both a Shift and Alt + if ( (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_MENU)) ) return -1; + // --------------------- // Return if we don't have both a Wiimote and Shift - if ( Wiimote && !GetAsyncKeyState(VK_SHIFT) ) return -1; + if ( Wiimote == 0 && !GetAsyncKeyState(VK_SHIFT) ) return -1; // Return if we don't have both a Nunchuck and Ctrl - if ( !Wiimote && !GetAsyncKeyState(VK_CONTROL) ) return -1; + if ( Wiimote == 1 && !GetAsyncKeyState(VK_CONTROL) ) return -1; + + // Return if we don't have both a IR call and Alt + if ( Wiimote == 2 && !GetAsyncKeyState(VK_MENU) ) return -1; // Check if we have exactly one numerical key int Keys = 0; @@ -279,13 +324,13 @@ void FillReportAcc(wm_accel& _acc) // Check for a playback command if(g_RecordingPlaying[0] < 0) { - g_RecordingPlaying[0] = RecordingCheckKeys(true); + g_RecordingPlaying[0] = RecordingCheckKeys(0); } else { - RecordingPlay(_acc.x, _acc.y, _acc.z, 0); + // If the recording reached the end or failed somehow we will not return + if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0)) return; //Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z); - if (_acc.x != 0 && _acc.y != 0 && _acc.z != 0) return; } // --------------------- @@ -481,10 +526,27 @@ void FillReportAcc(wm_accel& _acc) // --------------- void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) { + // ------------------------------------ + // Recorded movements + // -------------- + // Check for a playback command + if(g_RecordingPlaying[2] < 0) + { + g_RecordingPlaying[2] = RecordingCheckKeys(2); + } + else + { + //Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z); + if (RecordingPlayIR(_ir0)) return; + } + // --------------------- -/* DESCRIPTION: The calibration is controlled by these values, their absolute value and - the relative distance between between them control the calibration. WideScreen mode - has its own settings. */ + + // -------------------------------------- + /* The calibration is controlled by these values, their absolute value and + the relative distance between between them control the calibration. WideScreen mode + has its own settings. */ + // ---------- int Top, Left, Right, Bottom, SensorBarRadius; if(g_Config.bWideScreen) { @@ -496,9 +558,10 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) Top = TOP; Left = LEFT; Right = RIGHT; Bottom = BOTTOM; SensorBarRadius = SENSOR_BAR_RADIUS; } + // ------------------ - /* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it sees to ojbects, at least from - how WiiMoteReal::SendEvent() works. */ + /* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it doesn't see a certain point, + at least from how WiiMoteReal::SendEvent() works. */ memset(&_ir0, 0xff, sizeof(wm_ir_extended)); memset(&_ir1, 0xff, sizeof(wm_ir_extended)); @@ -508,6 +571,9 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) // If we are outside the screen leave the values at 0xff if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return; + // -------------------------------------- + // Actual position calculation + // ---------- int y0 = Top + (MouseY * (Bottom - Top)); int y1 = Top + (MouseY * (Bottom - Top)); @@ -527,7 +593,7 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) _ir1.size = 10; _ir1.xHi = x1 >> 8; _ir1.yHi = y1 >> 8; - + // ------------------ // ---------------------------- // Debugging for calibration @@ -565,14 +631,33 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1) _ir0.y, _ir0.yHi, _ir1.y, _ir1.yHi, _ir0.size, _ir1.size );*/ + // ------------------ } /////////////////////////////////////////////////////////////////// -// The extended 10 byte reporting +// The 10 byte reporting used when an extension is connected // --------------- void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) { - /* See description above */ + // ------------------------------------ + // Recorded movements + // -------------- + // Check for a playback command + if(g_RecordingPlaying[2] < 0) + { + g_RecordingPlaying[2] = RecordingCheckKeys(2); + } + // We are playing back a recording, we don't accept any manual input this time + else + { + //Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z); + if (RecordingPlayIR(_ir0)) return; + } + // --------------------- + + // -------------------------------------- + /* See calibration description above */ + // ---------- int Top, Left, Right, Bottom, SensorBarRadius; if(g_Config.bWideScreen) @@ -585,6 +670,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) Top = TOP; Left = LEFT; Right = RIGHT; Bottom = BOTTOM; SensorBarRadius = SENSOR_BAR_RADIUS; } + // ------------------ // Fill with 0xff if empty memset(&_ir0, 0xff, sizeof(wm_ir_basic)); @@ -602,8 +688,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) int x1 = Left + (MouseX * (Right - Left)) - SensorBarRadius; int x2 = Left + (MouseX * (Right - Left)) + SensorBarRadius; - /* As with the extented report we settle with emulating two out of four - possible objects */ + /* As with the extented report we settle with emulating two out of four possible objects */ x1 = 1023 - x1; _ir0.x1 = x1 & 0xff; _ir0.y1 = y1 & 0xff; @@ -620,10 +705,10 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) //_ir1.x1Hi = (x1 >> 8) & 0x3; //_ir1.y1Hi = (y1 >> 8) & 0x3; - // ---------------------------- + // ------------------------------------ // Debugging for calibration - // ---------- - + // ---------- + /* if(GetAsyncKeyState(VK_NUMPAD1)) Right +=1; else if(GetAsyncKeyState(VK_NUMPAD2)) @@ -644,7 +729,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) SensorBarRadius += 1; else if(GetAsyncKeyState(VK_DELETE)) SensorBarRadius -= 1; -/* + //ClearScreen(); //if(consoleDisplay == 1) @@ -658,53 +743,56 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1) _ir1.x1, _ir1.x1Hi, _ir1.x2, _ir1.x2Hi, _ir1.y1, _ir1.y1Hi, _ir1.y2, _ir1.y2Hi );*/ + // ------------------ } -int abc = 0; + +//************************************************************************************** +// Extensions +//************************************************************************************** + + // =================================================== /* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes are JX JY AX AY AZ BT. */ // ---------------- void FillReportExtension(wm_extension& _ext) { -#ifdef _WIN32 // ------------------------------------ // Recorded movements // -------------- // Check for a playback command if(g_RecordingPlaying[1] < 0) { - g_RecordingPlaying[1] = RecordingCheckKeys(false); + g_RecordingPlaying[1] = RecordingCheckKeys(1); + } + // We should play back the accelerometer values else { - RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1); //Console::Print("X: %u\n", _acc.x); - return; + // + if (!RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1)) + { + /* These are the default neutral values for the nunchuck accelerometer according to the calibration + data we have in nunchuck_calibration[] */ + _ext.ax = 0x80; + _ext.ay = 0x80; + _ext.az = 0xb3; + } } // --------------------- -#endif - /* These are the default neutral values for the nunchuck accelerometer according - to a source. */ - _ext.ax = 0x80; - _ext.ay = 0x80; - _ext.az = 0xb3; - - - _ext.ax += abc; - - abc ++; - if (abc > 50) abc = 0; - - - _ext.jx = 0x80; // these are the default values unless we use them + // ------------------------------------ + // The default joystick and button values unless we use them + // -------------- + _ext.jx = 0x80; _ext.jy = 0x80; _ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active - + // --------------------- + #ifdef _WIN32 - /* We use a 192 range (32 to 224) that match our calibration values in - nunchuck_calibration */ + /* We use a 192 range (32 to 224) that match our calibration values in nunchuck_calibration[] */ if(GetAsyncKeyState(VK_NUMPAD4)) // left _ext.jx = 0x20; diff --git a/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp b/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp index b9be2a06b8..28ec7d32ac 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ReadWiimote.cpp @@ -53,12 +53,30 @@ void handle_ctrl_status(struct wiimote_t* wm) printf("battery: %f %%\n", wm->battery_level); } + +bool IRDataOK(struct wiimote_t* wm) +{ + //Console::Print("IRDataOK: "); + // The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte + int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18; + for(int i = 0; i < ReportSize; i++) + { + //Console::Print("%02x ", wm->event_buf[i]); + if (wm->event_buf[i] > 0) + { + //Console::Print("\n"); + return true; + } + } + return false; +} + void handle_event(struct wiimote_t* wm) { printf("\n\n--- EVENT [id %i] ---\n", wm->unid); /* if a button is pressed, report it */ - //if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n"); + if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)) Console::Print("B pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) Console::Print("UP pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) Console::Print("DOWN pressed\n"); @@ -78,22 +96,19 @@ void handle_event(struct wiimote_t* wm) if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) { wiiuse_motion_sensing(wm, 0); + wiiuse_set_ir(wm, 0); g_MotionSensing = false; } - /* - * Pressing plus will tell the wiimote we are interested in movement. - */ + // Turn aceelerometer and IR reporting on, there is some kind of bug that prevents us from turing these on + // directly after each other, so we have to wait for another wiiuse_poll() this way if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) { wiiuse_motion_sensing(wm, 1); g_MotionSensing = true; } - - // Turn IR reporting on and off - if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP)) + // Turn IR reporting on + if (g_MotionSensing && !WIIUSE_USING_IR(wm)) wiiuse_set_ir(wm, 1); - if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) - wiiuse_set_ir(wm, 0); /* Print battery status */ if(frame) @@ -101,15 +116,42 @@ void handle_event(struct wiimote_t* wm) frame->m_GaugeBattery->SetValue((int)floor((wm->battery_level * 100) + 0.5)); /* If the accelerometer is turned on then print angles */ - if (WIIUSE_USING_ACC(wm)) + if (WIIUSE_USING_ACC(wm) && WIIUSE_USING_IR(wm)) { - std::string Tmp; Tmp += StringFromFormat("Roll: %2.1f ", wm->orient.roll); Tmp += StringFromFormat("Pitch: %2.1f ", wm->orient.pitch); Tmp += StringFromFormat("Battery: %1.2f\n", wm->battery_level); Tmp += StringFromFormat("G-Force x, y, z: %1.2f %1.2f %1.2f\n", wm->gforce.x, wm->gforce.y, wm->gforce.z); - Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n\n", wm->accel.x, wm->accel.y, wm->accel.z); + Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z); + + // The report size is 0x33 = 18, 0x37 = 22 + int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18; + + // wm->event_buf is cleared at the end of all wiiuse_poll(), so wm->event_buf will always be zero + // after that. To get the raw IR data we need to read the wiimote again. This seems to work most of the time, + // it seems to fails with a regular interval about each tenth read. + if(wiiuse_io_read(wm)) + { + // Check that it's not zero + if (IRDataOK(wm)) memcpy(g_EventBuffer, wm->event_buf, ReportSize); + } + + // Go through each of the 4 possible IR sources + for (int i = 0; i < 4; ++i) + { + // Check if the source is visible + if (wm->ir.dot[i].visible) + Tmp += StringFromFormat("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y); + } + + Tmp += StringFromFormat("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y); + Tmp += StringFromFormat("IR z distance: %f\n", wm->ir.z); + std::string TmpData = ArrayToString(g_EventBuffer, ReportSize, 0, 30); + Tmp += "Data: " + TmpData; + + Console::ClearScreen(); + Console::Print("%s\n\n", Tmp.c_str()); if(frame) { @@ -129,11 +171,19 @@ void handle_event(struct wiimote_t* wm) frame->m_GaugeAccel[1]->SetValue(wm->accel.y); frame->m_GaugeAccel[2]->SetValue(wm->accel.z); + frame->m_TextIR->SetLabel(wxString::Format( + "Cursor: %03u %03u\nDistance:%4.0f", wm->ir.x, wm->ir.y, wm->ir.z)); + 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); } + + // Send the data to be saved + //const u8* data = (const u8*)wm->event_buf; + frame->DoRecordMovement(wm->accel.x, wm->accel.y, wm->accel.z, (g_EventBuffer + 6), + (WIIUSE_USING_EXP(wm) ? 10 : 12)); - frame->DoRecordMovement(wm->accel.x, wm->accel.y, wm->accel.z); + // Turn recording on and off if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) frame->DoRecordA(true); else frame->DoRecordA(false); } @@ -143,43 +193,20 @@ void handle_event(struct wiimote_t* wm) { if (frame) { + frame->m_GaugeRoll[0]->SetValue(0); + frame->m_GaugeRoll[1]->SetValue(0); + + frame->m_GaugeGForce[0]->SetValue(0); + frame->m_GaugeGForce[1]->SetValue(0); + frame->m_GaugeGForce[2]->SetValue(0); + frame->m_GaugeAccel[0]->SetValue(0); frame->m_GaugeAccel[1]->SetValue(0); frame->m_GaugeAccel[2]->SetValue(0); + + frame->m_TextIR->SetLabel(wxT("Cursor:\nDistance:")); } } - - - /* - * If IR tracking is enabled then print the coordinates - * on the virtual screen that the wiimote is pointing to. - * - * Also make sure that we see at least 1 dot. - */ - if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP)) - wiiuse_set_ir(wm, 1); - if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) - wiiuse_set_ir(wm, 0); - - if (WIIUSE_USING_IR(wm)) - { - /*Console::ClearScreen(); - - // Go through each of the 4 possible IR sources - for (int i = 0; i < 4; ++i) - { - // Check if the source is visible - if (wm->ir.dot[i].visible) - Console::Print("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y); - } - - Console::Print("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y); - Console::Print("IR z distance: %f\n", wm->ir.z); - - const byte* pBuffer = wm->event_buf; - std::string Temp = ArrayToString(pBuffer, 20, 0, 30); - Console::Print("Data: %s\n", Temp.c_str());*/ - } } void ReadWiimote() @@ -246,13 +273,13 @@ void ReadWiimote() break; case WIIUSE_CLASSIC_CTRL_INSERTED: - //printf("Classic controller inserted.\n"); + Console::Print("Classic controller inserted.\n"); break; case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: /* some expansion was inserted */ //handle_ctrl_status(wiimotes[i]); - printf("Guitar Hero 3 controller inserted.\n"); + Console::Print("Guitar Hero 3 controller inserted.\n"); break; case WIIUSE_NUNCHUK_REMOVED: @@ -260,7 +287,7 @@ void ReadWiimote() case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: /* some expansion was removed */ //handle_ctrl_status(wiimotes[i]); - printf("An expansion was removed.\n"); + Console::Print("An expansion was removed.\n"); break; default: diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.h b/Source/Plugins/Plugin_Wiimote/Src/main.h index 3706ae8cf3..cc91acc6f0 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.h +++ b/Source/Plugins/Plugin_Wiimote/Src/main.h @@ -46,18 +46,23 @@ bool IsFocus(); // Movement recording #define RECORDING_ROWS 15 +#define WM_RECORDING_WIIMOTE 0 +#define WM_RECORDING_NUNCHUCK 1 +#define WM_RECORDING_IR 2 struct SRecording { u8 x; u8 y; u8 z; double Time; + u8 IR[12]; }; struct SRecordingAll { std::vector Recording; int HotKey; int PlaybackSpeed; + int IRBytes; }; #ifndef EXCLUDEMAIN_H diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h index eee012a6b3..f87ad3cd41 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_hid.h @@ -154,7 +154,7 @@ struct wm_accel { u8 x, y, z; }; -//filled with 0xFF if empty +// Filled with 0xFF if empty struct wm_ir_basic { u8 x1; diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index cf631943ec..2da283d5eb 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -70,10 +70,12 @@ int g_NumberOfWiiMotes; CWiiMote* g_WiiMotes[MAX_WIIMOTES]; bool g_Shutdown = false; bool g_LocalThread = true; +bool g_IRSensing = false; bool g_MotionSensing = false; u64 g_UpdateTime = 0; int g_UpdateCounter = 0; bool g_RunTemporary = false; +u8 g_EventBuffer[32]; //****************************************************************************** // Probably this class should be in its own file diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h index 5d36fc25ee..8bd98df26e 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h @@ -48,9 +48,11 @@ void ReadWiimote(); extern wiimote_t** g_WiiMotesFromWiiUse; extern int g_NumberOfWiiMotes; extern bool g_MotionSensing; + extern bool g_IRSensing; extern u64 g_UpdateTime; extern int g_UpdateCounter; extern bool g_RunTemporary; + extern u8 g_EventBuffer[32]; #endif }; // WiiMoteReal