From c43d8e9dcd1e08acf1b2287c4b64f5a9f31c8fab Mon Sep 17 00:00:00 2001 From: John Peterson Date: Wed, 4 Feb 2009 13:35:28 +0000 Subject: [PATCH] Wiimote: Added new gamepad controller options to the GUI, they are not connected yet git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2108 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_Wiimote/Plugin_Wiimote.vcproj | 6 +- .../Plugins/Plugin_Wiimote/Src/ConfigDlg.cpp | 906 +++++++----------- Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h | 34 +- .../Plugin_Wiimote/Src/ConfigRecording.cpp | 530 ++++++++++ Source/Plugins/Plugin_Wiimote/Src/SConscript | 1 + Source/Plugins/Plugin_Wiimote/Src/main.cpp | 16 +- 6 files changed, 886 insertions(+), 607 deletions(-) create mode 100644 Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp diff --git a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj index e492a8c5b8..9c5e5b6861 100644 --- a/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj +++ b/Source/Plugins/Plugin_Wiimote/Plugin_Wiimote.vcproj @@ -1,7 +1,7 @@ + + SetSelection(TmpRecordHotKey); - - // Movement name - std::string TmpMovementName; file.Get(SaveName.c_str(), "MovementName", &TmpMovementName, ""); - m_RecordText[i]->SetValue(wxString::FromAscii(TmpMovementName.c_str())); - - // Game name - 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) - m_RecordSpeed[i]->SetValue(wxString::Format(wxT("%i"), TmpRecordSpeed)); - else - m_RecordSpeed[i]->SetValue(wxT("")); - - // Playback speed (currently always saved directly after a recording) - int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1); - m_RecordPlayBackSpeed[i]->SetSelection(TmpPlaybackSpeed); - } -} -void ConfigDialog::SaveFile() + CTL_TRIGGER_SDL = 0, // + CTL_TRIGGER_XINPUT // The XBox 360 pad +}; +// Trigger type +static const char* TriggerType[] = { - Console::Print("SaveFile\n"); + "SDL", // -0x8000 to 0x7fff + "XInput", // 0x00 to 0xff +}; +////////////////////////////////////// - IniFile file; - file.Load("WiimoteMovement.ini"); +////////////////////////////////////////////////////////////////////////////////////////// +// Bitmap box and dot +// ---------------- +wxBitmap ConfigDialog::CreateBitmap() +{ + BoxW = 70, BoxH = 70; + wxBitmap bitmap(BoxW, BoxH); + wxMemoryDC dc; + dc.SelectObject(bitmap); - for(int i = 1; i < (RECORDING_ROWS + 1); i++) - { - // Get row name - std::string SaveName = StringFromFormat("Recording%i", i); + // Set outline and fill colors + //wxBrush LightBlueBrush(_T("#0383f0")); + //wxPen LightBluePen(_T("#80c5fd")); + //wxPen LightGrayPen(_T("#909090")); + wxPen LightBluePen(_T("#7f9db9")); // Windows XP color + dc.SetPen(LightBluePen); + dc.SetBrush(*wxWHITE_BRUSH); - // HotKey - file.Set(SaveName.c_str(), "HotKey", m_RecordHotKey[i]->GetSelection()); - - // Movement name - file.Set(SaveName.c_str(), "MovementName", m_RecordText[i]->GetValue().c_str()); - - // Game name - file.Set(SaveName.c_str(), "GameName", m_RecordGameText[i]->GetValue().c_str()); - - // Recording speed (currently always saved directly after a recording) - /* - wxString TmpRecordSpeed = m_RecordSpeed[i]->GetValue(); - if(TmpRecordSpeed.length() > 0) - int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", TmpRecordSpeed); - else - int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", "-1"); - */ - - // Playback speed (currently always saved directly after a recording) - file.Set(SaveName.c_str(), "PlaybackSpeed", m_RecordPlayBackSpeed[i]->GetSelection()); - } - - file.Save("WiimoteMovement.ini"); + dc.Clear(); + dc.DrawRectangle(0, 0, BoxW, BoxH); + dc.SelectObject(wxNullBitmap); + return bitmap; } -///////////////////////////// +wxBitmap ConfigDialog::CreateBitmapDot() +{ + int w = 2, h = 2; + wxBitmap bitmap(w, h); + wxMemoryDC dc; + dc.SelectObject(bitmap); + + // Set outline and fill colors + //wxBrush RedBrush(_T("#0383f0")); + //wxPen RedPen(_T("#80c5fd")); + //wxPen LightGrayPen(_T("#909090")); + dc.SetPen(*wxRED_PEN); + dc.SetBrush(*wxRED_BRUSH); + + dc.Clear(); + dc.DrawRectangle(0, 0, w, h); + dc.SelectObject(wxNullBitmap); + return bitmap; +} +////////////////////////////////////// -///////////////////////////////////////////////////////////////////////// -// Create GUI -// ------------ void ConfigDialog::CreateGUIControls() { - // Notebook - m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); - m_PageEmu = new wxPanel(m_Notebook, ID_PAGEEMU, wxDefaultPosition, wxDefaultSize); - m_PageReal = new wxPanel(m_Notebook, ID_PAGEREAL, wxDefaultPosition, wxDefaultSize); - m_Notebook->AddPage(m_PageEmu, wxT("Emulated Wiimote")); - m_Notebook->AddPage(m_PageReal, wxT("Real Wiimote")); + //////////////////////////////////////////////////////////////////////////////// + // Notebook + // ---------------- + m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); + + // Controller pages + m_Controller[0] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1, wxDefaultPosition, wxDefaultSize); + m_Controller[1] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE2, wxDefaultPosition, wxDefaultSize); + m_Controller[2] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE3, wxDefaultPosition, wxDefaultSize); + m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxDefaultPosition, wxDefaultSize); + m_PageRecording = new wxPanel(m_Notebook, ID_PAGE_RECORDING, wxDefaultPosition, wxDefaultSize); + + m_Notebook->AddPage(m_Controller[0], wxT("Controller 1")); + m_Notebook->AddPage(m_Controller[1], wxT("Controller 2")); + m_Notebook->AddPage(m_Controller[2], wxT("Controller 3")); + m_Notebook->AddPage(m_Controller[3], wxT("Controller 4")); + m_Notebook->AddPage(m_PageRecording, wxT("Recording")); + /////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// + // Text lists + // ---------------- + + // Search for devices and add them to the device list + wxArrayString StrJoyname; // The string array + int NumGoodPads = 0; + if(NumGoodPads > 0) + { + //for(int x = 0; x < joyinfo.size(); x++) + // arrayStringFor_Joyname.Add(wxString::FromAscii(joyinfo[x].Name.c_str())); + } + else + { + StrJoyname.Add(wxString::FromAscii("No Joystick detected")); + } + + // The tilt list + wxArrayString StrTilt; + StrTilt.Add(wxString::FromAscii("")); + StrTilt.Add(wxString::FromAscii("Analog stick")); + StrTilt.Add(wxString::FromAscii("Triggers")); + StrTilt.Add(wxString::FromAscii("Keyboard")); + wxArrayString StrTiltRange; + for (int i = 3; i < 15; i++) StrTiltRange.Add(wxString::Format(wxT("%i"), i*5)); + + + // The Trigger type list + wxArrayString wxAS_TriggerType; + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_SDL])); + wxAS_TriggerType.Add(wxString::FromAscii(TriggerType[CTL_TRIGGER_XINPUT])); + /////////////////////////////////////// + + + /* Populate all four pages. Page 2, 3 and 4 are currently disabled since we can't use more than one + Wiimote at the moment */ + for (int i = 0; i < 4; i++) + { + //////////////////////////////////////////////////// + // General and basic Settings + // ---------------- + + // Basic Settings + m_SidewaysDPad[i] = new wxCheckBox(m_Controller[i], ID_SIDEWAYSDPAD, wxT("Sideways D-Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_WideScreen[i] = new wxCheckBox(m_Controller[i], ID_WIDESCREEN, wxT("WideScreen Mode (for correct aiming)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_ConnectRealWiimote[i] = new wxCheckBox(m_Controller[i], ID_CONNECT_REAL, wxT("Connect Real Wiimote")); + m_UseRealWiimote[i] = new wxCheckBox(m_Controller[i], ID_USE_REAL, wxT("Use Real Wiimote")); + + // Extensions + m_NunchuckConnected[i] = new wxCheckBox(m_Controller[i], ID_NUNCHUCKCONNECTED, wxT("Nunchuck Connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_ClassicControllerConnected[i] = new wxCheckBox(m_Controller[i], ID_CLASSICCONTROLLERCONNECTED, wxT("Classic Controller Connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + + // Default values + m_NunchuckConnected[i]->SetValue(g_Config.bNunchuckConnected); + m_ClassicControllerConnected[i]->SetValue(g_Config.bClassicControllerConnected); + + // Sizers + m_SizeBasic[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Basic Settings")); + m_SizeExtensions[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Extension")); + + m_SizePadding[i] = new wxBoxSizer(wxVERTICAL); m_SizeBasic[i]->Add(m_SizePadding[i], 0, (wxALL), 5); + m_SizePadding[i]->Add(m_ConnectRealWiimote[i], 0, (wxUP), 2); + m_SizePadding[i]->Add(m_UseRealWiimote[i], 0, (wxUP), 2); + m_SizePadding[i]->Add(m_SidewaysDPad[i], 0, (wxUP), 2); + m_SizePadding[i]->Add(m_WideScreen[i], 0, (wxUP), 2); + + m_SizeExtensionsPadding[i] = new wxBoxSizer(wxVERTICAL); m_SizeExtensions[i]->Add(m_SizeExtensionsPadding[i], 0, (wxALL), 5); + m_SizeExtensionsPadding[i]->Add(m_NunchuckConnected[i], 0, (wxUP), 2); + m_SizeExtensionsPadding[i]->Add(m_ClassicControllerConnected[i], 0, (wxUP), 2); + + m_SizeBasicGeneral[i] = new wxBoxSizer(wxHORIZONTAL); + m_SizeBasicGeneral[i]->Add(m_SizeBasic[i], 0, (wxUP), 0); + m_SizeBasicGeneral[i]->Add(m_SizeExtensions[i], 0, (wxLEFT), 5); + + // Default values + m_SidewaysDPad[i]->SetValue(g_Config.bSidewaysDPad); + m_WideScreen[i]->SetValue(g_Config.bWideScreen); + m_ConnectRealWiimote[i]->SetValue(g_Config.bConnectRealWiimote); + m_UseRealWiimote[i]->SetValue(g_Config.bUseRealWiimote); + + // Tooltips + m_ConnectRealWiimote[i]->SetToolTip(wxT("Connected to the real wiimote. This can not be changed during gameplay.")); + m_UseRealWiimote[i]->SetToolTip(wxT( + "Use the real Wiimote in the game. This can be changed during gameplay. This can not be selected" + " when a recording is to be done. No status in this window will be updated when this is checked.")); + /////////////////////////// + + + //////////////////////////////////////////////////////////////////////// + // Gamepad input + // ---------------- + + // -------------------------------------------------------------------- + // Controller + // ----------------------------- + /**/ + // Controls + m_Joyname[i] = new wxComboBox(m_Controller[i], IDC_JOYNAME, StrJoyname[0], wxDefaultPosition, wxSize(476, 21), StrJoyname, wxCB_READONLY); + m_Joyattach[i] = new wxCheckBox(m_Controller[i], IDC_JOYATTACH, wxT("Controller attached"), wxDefaultPosition, wxSize(109, 25)); + + m_gJoyname[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Controller:")); + m_gJoyname[i]->Add(m_Joyname[i], 0, (wxLEFT | wxRIGHT), 5); + m_gJoyname[i]->Add(m_Joyattach[i], 0, (wxRIGHT | wxLEFT | wxBOTTOM), 1); + + // Tooltips + m_Joyattach[i]->SetToolTip(wxString::Format(wxT("Decide if Controller %i shall be detected by the game."), 1)); + m_Joyname[i]->SetToolTip(wxT("Save your settings and configure another joypad")); + + + // -------------------------------------------------------------------- + // Analog sticks + // ----------------------------- + /**/ + m_pInStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDot[i] = new wxStaticBitmap(m_pInStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + m_pRightStatus[i] = new wxPanel(m_Controller[i], wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_bmpSquareRight[i] = new wxStaticBitmap(m_pRightStatus[i], wxID_ANY, CreateBitmap(), wxDefaultPosition, wxDefaultSize); + m_bmpDotRight[i] = new wxStaticBitmap(m_pRightStatus[i], wxID_ANY, CreateBitmapDot(), wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); + + m_gAnalogLeft[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 1")); + m_gAnalogLeft[i]->Add(m_pInStatus[i], 0, (wxLEFT | wxRIGHT), 5); + + m_gAnalogRight[i] = new wxStaticBoxSizer (wxHORIZONTAL, m_Controller[i], wxT("Analog 2")); + m_gAnalogRight[i]->Add(m_pRightStatus[i], 0, (wxLEFT | wxRIGHT), 5); + + // -------------------------------------------------------------------- + // Tilt Wiimote + // ----------------------------- + /**/ + // 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_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]->Add(m_TiltCombo[i], 0, (wxLEFT | wxRIGHT | wxDOWN), 5); + m_gTilt[i]->Add(m_TiltHoriz[i], 0, (wxLEFT | wxRIGHT), 5); + + // Tooltips + m_TiltCombo[i]->SetToolTip(wxT("Control tilting by an analog gamepad stick, an analog trigger or the keyboard.")); + + // Sizers + m_HorizControllers[i] = new wxBoxSizer(wxHORIZONTAL); + m_HorizControllers[i]->Add(m_gAnalogLeft[i]); + m_HorizControllers[i]->Add(m_gAnalogRight[i], 0, (wxLEFT), 5); + m_HorizControllers[i]->Add(m_gTilt[i], 0, (wxLEFT), 5); + /////////////////////////// + + + //////////////////////////////////////////////////////////////// + // Set up sizers and layout + // Usage: The wxGBPosition() must have a column and row + // ---------------- + m_sMain[i] = new wxBoxSizer(wxVERTICAL); + m_sMain[i]->Add(m_SizeBasicGeneral[i], 0, wxEXPAND | (wxALL), 5); + m_sMain[i]->Add(m_gJoyname[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + m_sMain[i]->Add(m_HorizControllers[i], 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + + m_Controller[i]->SetSizer(m_sMain[i]); // Set the main sizer + ///////////////////////////////// + } + + //////////////////////////////////////////// + // Movement recording + // ---------------- + CreateGUIControlsRecording(); + ///////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////// // Buttons //m_About = new wxButton(this, ID_ABOUTOGL, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Apply = new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Close = new wxButton(this, ID_CLOSE, wxT("Close")); m_Close->SetToolTip(wxT("Apply and Close")); - //////////////////////////////////////////// - // Put notebook and buttons in sMain - // ---------------- - wxBoxSizer* sButtons; - sButtons = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL); //sButtons->Add(m_About, 0, wxALL, 5); // there is no about sButtons->AddStretchSpacer(); sButtons->Add(m_Apply, 0, (wxALL), 0); sButtons->Add(m_Close, 0, (wxLEFT), 5); - - wxBoxSizer* sMain; - sMain = new wxBoxSizer(wxVERTICAL); - sMain->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); - sMain->Add(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); - ///////////////////////////////// - - - //////////////////////////////////////////// - // Emulated Wiimote - // ---------------- - // General - wxStaticBoxSizer * sEmulatedBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageEmu, wxT("Basic Settings")); - m_SidewaysDPad = new wxCheckBox(m_PageEmu, ID_SIDEWAYSDPAD, wxT("Sideways D-Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_SidewaysDPad->SetValue(g_Config.bSidewaysDPad); - m_WideScreen = new wxCheckBox(m_PageEmu, ID_WIDESCREEN, wxT("WideScreen Mode (for correct aiming)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_WideScreen->SetValue(g_Config.bWideScreen); - m_NunchuckConnected = new wxCheckBox(m_PageEmu, ID_NUNCHUCKCONNECTED, wxT("Nunchuck connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_NunchuckConnected->SetValue(g_Config.bNunchuckConnected); - m_ClassicControllerConnected = new wxCheckBox(m_PageEmu, ID_CLASSICCONTROLLERCONNECTED, wxT("Classic Controller connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected); - - // ---------------------------------------------------------------------- - // Set up sGeneral and sBasic - // Usage: The wxGBPosition() must have a column and row - // ---------------- - wxBoxSizer * sEmulatedMain = new wxBoxSizer(wxVERTICAL); - wxGridBagSizer * GbsBasic = new wxGridBagSizer(0, 0); - GbsBasic->Add(m_SidewaysDPad, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5); - GbsBasic->Add(m_WideScreen, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5); - GbsBasic->Add(m_NunchuckConnected, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5); - GbsBasic->Add(m_ClassicControllerConnected, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5); - sEmulatedBasic->Add(GbsBasic); - sEmulatedMain->Add(sEmulatedBasic, 0, wxEXPAND | (wxALL), 5); - ///////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////// - // Real Wiimote - // ---------------- - // Basic Settings - wxStaticBoxSizer * sbRealBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Basic Settings")); - m_ConnectRealWiimote = new wxCheckBox(m_PageReal, ID_CONNECT_REAL, wxT("Connect real Wiimote")); - m_UseRealWiimote = new wxCheckBox(m_PageReal, ID_USE_REAL, wxT("Use real Wiimote")); - m_ConnectRealWiimote->SetToolTip(wxT("Connected to the real wiimote. This can not be changed during gameplay.")); - m_UseRealWiimote->SetToolTip(wxT( - "Use the real Wiimote in the game. This can be changed during gameplay. This can not be selected" - " when a recording is to be done. No status in this window will be updated when this is checked.")); - m_ConnectRealWiimote->SetValue(g_Config.bConnectRealWiimote); - m_UseRealWiimote->SetValue(g_Config.bUseRealWiimote); - - // --------------------------------------------- - // Status - // ---------------- - wxStaticBoxSizer * sbRealStatus = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Status")); - m_TextUpdateRate = new wxStaticText(m_PageReal, wxID_ANY, wxT("Update rate: 000 times/s")); - m_UpdateMeters = new wxCheckBox(m_PageReal, ID_UPDATE_REAL, wxT("Update gauges")); - - m_UpdateMeters->SetValue(g_Config.bUpdateRealWiimote); - - m_UpdateMeters->SetToolTip(wxT( - "You can turn this off when a game is running to avoid a potential slowdown that may come from redrawing the\n" - "configuration screen. Remember that you also need to press '+' on your Wiimote before you can record movements." - )); - - sbRealStatus->Add(m_TextUpdateRate, 0, wxEXPAND | (wxALL), 5); - sbRealStatus->Add(m_UpdateMeters, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxUP), 5); - // ----------------------- - - // --------------------------------------------- - // Wiimote accelerometer neutral values - // ---------------- - wxStaticBoxSizer * sbRealNeutral = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Wiimote neutral")); - wxStaticText * m_TextAccNeutralTarget = new wxStaticText(m_PageReal, wxID_ANY, wxT("Target: 132 132 159")); - m_TextAccNeutralCurrent = new wxStaticText(m_PageReal, wxID_ANY, wxT("Current: 000 000 000")); - wxArrayString StrAccNeutral; - for(int i = 0; i < 31; i++) StrAccNeutral.Add(wxString::Format(wxT("%i"), i)); - for(int i = 0; i < 3; i++) m_AccNeutralChoice[i] = new wxChoice(m_PageReal, ID_NEUTRAL_CHOICE, wxDefaultPosition, wxDefaultSize, StrAccNeutral); - m_AccNeutralChoice[0]->SetSelection(g_Config.iAccNeutralX); - m_AccNeutralChoice[1]->SetSelection(g_Config.iAccNeutralY); - m_AccNeutralChoice[2]->SetSelection(g_Config.iAccNeutralZ); - - wxBoxSizer * sbRealWiimoteNeutralChoices = new wxBoxSizer(wxHORIZONTAL); - sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[0], 0, wxEXPAND | (wxALL), 0); - sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[1], 0, wxEXPAND | (wxLEFT), 2); - sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[2], 0, wxEXPAND | (wxLEFT), 2); - - sbRealNeutral->Add(m_TextAccNeutralTarget, 0, wxEXPAND | (wxALL), 5); - sbRealNeutral->Add(m_TextAccNeutralCurrent, 0, wxEXPAND | (wxLEFT | wxRIGHT), 5); - sbRealNeutral->Add(sbRealWiimoteNeutralChoices, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxUP), 5); - - m_TextAccNeutralTarget->SetToolTip(wxT( - "To produce compatible accelerometer recordings that can be shared with other users without problems" - " you have to adjust the Current value to the Target value before you make a recording." - )); - - // Wiimote Status - wxBoxSizer * sbRealWiimoteStatus = new wxBoxSizer(wxHORIZONTAL); - - wxStaticBoxSizer * sbRealBattery = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Battery")); - 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; - - m_GaugeBattery = new wxGauge( m_PageReal, wxID_ANY, 100, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeRoll[0] = new wxGauge( m_PageReal, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeRoll[1] = new wxGauge( m_PageReal, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeGForce[0] = new wxGauge( m_PageReal, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeGForce[1] = new wxGauge( m_PageReal, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeGForce[2] = new wxGauge( m_PageReal, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - m_GaugeAccel[0] = new wxGauge( m_PageReal, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); - 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); - sBoxRoll[1] = new wxBoxSizer(wxVERTICAL); - wxBoxSizer * sBoxGForce[3]; - sBoxGForce[0] = new wxBoxSizer(wxVERTICAL); - sBoxGForce[1] = new wxBoxSizer(wxVERTICAL); - sBoxGForce[2] = new wxBoxSizer(wxVERTICAL); - wxBoxSizer * sBoxAccel[3]; - sBoxAccel[0] = new wxBoxSizer(wxVERTICAL); - sBoxAccel[1] = new wxBoxSizer(wxVERTICAL); - sBoxAccel[2] = new wxBoxSizer(wxVERTICAL); - - wxStaticText * m_TextBattery = new wxStaticText(m_PageReal, wxID_ANY, wxT("Batt."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - wxStaticText * m_TextRoll = new wxStaticText(m_PageReal, wxID_ANY, wxT("Roll"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - wxStaticText * m_TextPitch = new wxStaticText(m_PageReal, wxID_ANY, wxT("Pitch"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); - wxStaticText *m_TextX[2], *m_TextY[2], *m_TextZ[2]; - 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); - sBoxRoll[1]->Add(m_GaugeRoll[1], 0, wxEXPAND | (wxALL), 5); sBoxRoll[1]->Add(m_TextPitch, 0, wxEXPAND | (wxALL), 0); - - sBoxGForce[0]->Add(m_GaugeGForce[0], 0, wxEXPAND | (wxALL), 5); sBoxGForce[0]->Add(m_TextX[0], 0, wxEXPAND | (wxALL), 0); - sBoxGForce[1]->Add(m_GaugeGForce[1], 0, wxEXPAND | (wxALL), 5); sBoxGForce[1]->Add(m_TextY[0], 0, wxEXPAND | (wxALL), 0); - sBoxGForce[2]->Add(m_GaugeGForce[2], 0, wxEXPAND | (wxALL), 5); sBoxGForce[2]->Add(m_TextZ[0], 0, wxEXPAND | (wxALL), 0); - - sBoxAccel[0]->Add(m_GaugeAccel[0], 0, wxEXPAND | (wxALL), 5); sBoxAccel[0]->Add(m_TextX[1], 0, wxEXPAND | (wxALL), 0); - sBoxAccel[1]->Add(m_GaugeAccel[1], 0, wxEXPAND | (wxALL), 5); sBoxAccel[1]->Add(m_TextY[1], 0, wxEXPAND | (wxALL), 0); - sBoxAccel[2]->Add(m_GaugeAccel[2], 0, wxEXPAND | (wxALL), 5); sBoxAccel[2]->Add(m_TextZ[1], 0, wxEXPAND | (wxALL), 0); - - sbRealBattery->Add(sBoxBattery, 0, wxEXPAND | (wxALL), 5); - 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.")); - // ========================================== - - - // ==================================================================== - // Record movement - // ---------------- - wxStaticBoxSizer * sbRealRecord = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Record movements")); - - wxArrayString StrHotKey; - for(int i = 0; i < 10; i++) StrHotKey.Add(wxString::Format(wxT("%i"), i)); - StrHotKey.Add(wxT("")); - - wxArrayString StrPlayBackSpeed; - for(int i = 1; i <= 20; i++) StrPlayBackSpeed.Add(wxString::Format(wxT("%i"), i*25)); - - wxBoxSizer * sRealRecord[RECORDING_ROWS + 1]; - - wxStaticText * m_TextRec = new wxStaticText(m_PageReal, wxID_ANY, wxT("Rec."), wxDefaultPosition, wxSize(80, 15), wxALIGN_CENTRE); - 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_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" - "by letting go of 'A'")); - m_TextHotKey->SetToolTip(wxT("The HotKey is Shift + [Number] for Wiimote movements and Ctrl + [Number] for Nunchuck movements")); - m_TextRecSped->SetToolTip(wxT("Recording speed in average measurements per second")); - m_TextPlaySpeed->SetToolTip(wxT( - "Playback speed: A playback speed of 100 means that the playback occurs at the same rate as it was recorded. (You can see the\n" - "current update rate in the Status window above when a game is running.) However, if your framerate is only at 50% of full speed\n" - "you may want to select a playback rate of 50, because then the game might perceive the playback as a full speed playback. (This\n" - "holds if Wiimote_Update() is tied to the framerate, I'm not sure that this is the case. It seemed to vary somewhat with different\n" - "framerates but perhaps not enough to say that it was exactly tied to the framerate.) So until this is better understood you'll have\n" - "to try different playback rates and see which one that works." - )); - - sRealRecord[0] = new wxBoxSizer(wxHORIZONTAL); - sRealRecord[0]->Add(m_TextRec, 0, wxEXPAND | (wxLEFT), 5); - 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); - - for(int i = 1; i < (RECORDING_ROWS + 1); i++) - { - sRealRecord[i] = new wxBoxSizer(wxHORIZONTAL); - m_RecordButton[i] = new wxButton(m_PageReal, IDB_RECORD + i, wxEmptyString, wxDefaultPosition, wxSize(80, 20), 0, wxDefaultValidator, wxEmptyString); - 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); - - sbRealRecord->Add(sRealRecord[i], 0, wxEXPAND | (wxTOP), 2); - } - // ========================================== - - - // ---------------------------------------------------------------------- - // Set up sizers - // ---------------- - sbRealBasic->Add(m_ConnectRealWiimote, 0, wxEXPAND | (wxALL), 5); - sbRealBasic->Add(m_UseRealWiimote, 0, wxEXPAND | (wxALL), 5); - - wxBoxSizer * sRealBasicStatus = new wxBoxSizer(wxHORIZONTAL); - sRealBasicStatus->Add(sbRealBasic, 0, wxEXPAND | (wxLEFT), 0); - sRealBasicStatus->Add(sbRealStatus, 0, wxEXPAND | (wxLEFT), 5); - sRealBasicStatus->Add(sbRealNeutral, 0, wxEXPAND | (wxLEFT), 5); - - wxBoxSizer * sRealMain = new wxBoxSizer(wxVERTICAL); - sRealMain->Add(sRealBasicStatus, 0, wxEXPAND | (wxALL), 5); - sRealMain->Add(sbRealWiimoteStatus, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); - sRealMain->Add(sbRealRecord, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); - ///////////////////////////////// + /////////////////////////////// //////////////////////////////////////////// // Set sizers and layout // ---------------- - m_PageEmu->SetSizer(sEmulatedMain); - m_PageReal->SetSizer(sRealMain); - this->SetSizer(sMain); + m_MainSizer = new wxBoxSizer(wxVERTICAL); + m_MainSizer->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); + m_MainSizer->Add(sButtons, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); - //sEmulatedMain->Layout(); + m_Controller[1]->Enable(false); + m_Controller[2]->Enable(false); + m_Controller[3]->Enable(false); + + this->SetSizer(m_MainSizer); this->Layout(); Fit(); @@ -575,196 +505,13 @@ void ConfigDialog::CreateGUIControls() ///////////////////////////////// -///////////////////////////////////////////////////////////////////////// -/* Record movement */ -// ------------ - -void ConfigDialog::ConvertToString() -{ - // Load ini file - IniFile file; - file.Load("WiimoteMovement.ini"); - std::string TmpStr = "", TmpIR = "", TmpTime = ""; - - for (int i = 0; i < m_vRecording.size(); i++) - { - // Write the movement data - TmpStr += StringFromFormat("%02x", m_vRecording.at(i).x); - TmpStr += StringFromFormat("%02x", m_vRecording.at(i).y); - TmpStr += StringFromFormat("%02x", m_vRecording.at(i).z); - if(i < (m_vRecording.size() - 1)) TmpStr += ","; - - // 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 - double Recordings = (double)m_vRecording.size(); - double Time = m_vRecording.at(m_vRecording.size() - 1).Time - m_vRecording.at(0).Time; - int Rate = (int)(Recordings / Time); - - // If time or the number of recordings are zero we set the Rate to zero - 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 - int TmpPlaySpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaySpeed, -1); - if (TmpPlaySpeed == -1) - { - file.Set(SaveName.c_str(), "PlaybackSpeed", 3); - m_RecordPlayBackSpeed[m_iRecordTo]->SetSelection(3); - } - - file.Save("WiimoteMovement.ini"); -} - -// Timeout the recording -void ConfigDialog::Update(wxTimerEvent& WXUNUSED(event)) -{ - m_bWaitForRecording = false; - m_bRecording = false; - m_RecordButton[m_iRecordTo]->SetLabel(wxT("")); - UpdateGUI(); -} - -// One second timeout for another A press -void ConfigDialog::UpdateA(wxTimerEvent& WXUNUSED(event)) -{ - m_bAllowA = true; - Console::Print("A allowed again"); -} - -void ConfigDialog::RecordMovement(wxCommandEvent& event) -{ - m_iRecordTo = event.GetId() - 2000; - - if(WiiMoteReal::g_MotionSensing) - { - // Check if there already is a recording here - if(m_RecordSpeed[m_iRecordTo]->GetLineLength(0) > 0) - { - if(!AskYesNo("Do you want to replace the current recording?")) return; - } - m_RecordButton[m_iRecordTo]->SetLabel(wxT("Hold A")); - } - else - { - m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +")); - // This is for usability purposes, it may not be obvious at all that this must be unchecked - // for the recording to work - m_UseRealWiimote->SetValue(false); g_Config.bUseRealWiimote = false; - return; - } - - m_bWaitForRecording = true; - m_bAllowA = true; - m_bRecording = false; - - UpdateGUI(); - - m_TimeoutTimer->Start(5000, true); - //m_TimeoutATimer->Start(500, true); -} - -void ConfigDialog::DoRecordA(bool Pressed) -{ - // Return if we are not waiting or recording - if (! (m_bWaitForRecording || m_bRecording)) return; - - // Return if we are waiting but have not pressed A - if (m_bWaitForRecording && !Pressed) return; - - // Return if we are recording but are still pressing A - if (m_bRecording && Pressed) return; - - //m_bAllowA = false; - m_bRecording = Pressed; - - // Start recording, only run this once - if(m_bRecording && m_bWaitForRecording) - { - m_RecordButton[m_iRecordTo]->SetLabel(wxT("Recording...")); - m_vRecording.clear(); // Clear the list - m_TimeoutTimer->Stop(); - m_bWaitForRecording = false; - } - // The recording is done - else - { - m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done")); - Console::Print("Done: %i %i\n", m_bWaitForRecording, m_bRecording); - //m_bAllowA = true; - ConvertToString(); - } - - UpdateGUI(); -} - -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"); - - SRecording Tmp; - Tmp.x = _x; - 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) ) - { - m_bRecording = false; - m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done")); - ConvertToString(); - UpdateGUI(); - } -} -///////////////////////////////// - // =================================================== /* Do use real wiimote */ // ---------------- void ConfigDialog::DoConnectReal() { - g_Config.bConnectRealWiimote = m_ConnectRealWiimote->IsChecked(); + g_Config.bConnectRealWiimote = m_ConnectRealWiimote[Page]->IsChecked(); if(g_Config.bConnectRealWiimote) { @@ -793,7 +540,6 @@ void ConfigDialog::DoExtensionConnectedDisconnected() WiiMoteEmu::WmRequestStatus(WiiMoteEmu::g_ReportingChannel, rs); } - // =================================================== /* Change settings */ // ---------------- @@ -801,19 +547,31 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) { switch (event.GetId()) { + case ID_CONNECT_REAL: + DoConnectReal(); + break; + case ID_USE_REAL: + g_Config.bUseRealWiimote = m_UseRealWiimote[Page]->IsChecked(); + //if(g_Config.bUseRealWiimote) WiiMoteReal::SetDataReportingMode(); + if(g_Config.bUseRealWiimote) WiiMoteReal::ClearEvents(); + break; + case ID_SIDEWAYSDPAD: - g_Config.bSidewaysDPad = m_SidewaysDPad->IsChecked(); + g_Config.bSidewaysDPad = m_SidewaysDPad[Page]->IsChecked(); break; - case ID_WIDESCREEN: - g_Config.bWideScreen = m_WideScreen->IsChecked(); + g_Config.bWideScreen = m_WideScreen[Page]->IsChecked(); break; + + ////////////////////////// + // Extensions + // ----------- case ID_NUNCHUCKCONNECTED: // Don't allow two extensions at the same time - if(m_ClassicControllerConnected->IsChecked()) + if(m_ClassicControllerConnected[Page]->IsChecked()) { - m_ClassicControllerConnected->SetValue(false); + m_ClassicControllerConnected[Page]->SetValue(false); g_Config.bClassicControllerConnected = false; // Disconnect the extension so that the game recognize the change DoExtensionConnectedDisconnected(); @@ -823,7 +581,7 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) } // Update status - g_Config.bNunchuckConnected = m_NunchuckConnected->IsChecked(); + g_Config.bNunchuckConnected = m_NunchuckConnected[Page]->IsChecked(); // Copy the calibration data memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::nunchuck_calibration, @@ -836,15 +594,14 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) case ID_CLASSICCONTROLLERCONNECTED: // Don't allow two extensions at the same time - if(m_NunchuckConnected->IsChecked()) + if(m_NunchuckConnected[Page]->IsChecked()) { - m_NunchuckConnected->SetValue(false); + m_NunchuckConnected[Page]->SetValue(false); g_Config.bNunchuckConnected = false; // Disconnect the extension so that the game recognize the change DoExtensionConnectedDisconnected(); } - - g_Config.bClassicControllerConnected = m_ClassicControllerConnected->IsChecked(); + g_Config.bClassicControllerConnected = m_ClassicControllerConnected[Page]->IsChecked(); // Copy the calibration data memcpy(WiiMoteEmu::g_RegExt + 0x20, WiiMoteEmu::classic_calibration, @@ -855,17 +612,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) break; - ////////////////////////// - // Real Wiimote - // ----------- - case ID_CONNECT_REAL: - DoConnectReal(); - break; - case ID_USE_REAL: - g_Config.bUseRealWiimote = m_UseRealWiimote->IsChecked(); - //if(g_Config.bUseRealWiimote) WiiMoteReal::SetDataReportingMode(); - if(g_Config.bUseRealWiimote) WiiMoteReal::ClearEvents(); - break; + ////////////////////////// + // Recording + // ----------- case ID_UPDATE_REAL: g_Config.bUpdateRealWiimote = m_UpdateMeters->IsChecked(); break; @@ -922,22 +671,23 @@ void ConfigDialog::UpdateGUI() side by side so that we can switch between between during gameplay. We update the checked or unchecked values from the g_Config settings, and we make sure they are up to date with unplugged and reinserted extensions. */ - m_NunchuckConnected->SetValue(g_Config.bNunchuckConnected); - m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected); - m_NunchuckConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning)); - m_ClassicControllerConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning)); + m_NunchuckConnected[Page]->SetValue(g_Config.bNunchuckConnected); + m_ClassicControllerConnected[Page]->SetValue(g_Config.bClassicControllerConnected); + m_NunchuckConnected[Page]->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning)); + m_ClassicControllerConnected[Page]->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 mean that the wiimote must be sent the current reporting mode and the channel ID after it has been initialized. Functions for that are basically already in place so these two options could possibly be simplified to one option. */ - m_ConnectRealWiimote->Enable(!g_EmulatorRunning); - m_UseRealWiimote->Enable(!(g_EmulatorRunning && g_RealWiiMotePresent && g_Config.bConnectRealWiimote)); + m_ConnectRealWiimote[Page]->Enable(!g_EmulatorRunning); + m_UseRealWiimote[Page]->Enable((g_RealWiiMotePresent && g_Config.bConnectRealWiimote) || !g_EmulatorRunning); -// Linux has no FindItem() -#ifdef _WIN32 - for(int i = IDB_RECORD + 1; i < (IDB_RECORD + RECORDING_ROWS + 1); i++) - if(ControlsCreated) m_Notebook->FindItem(i)->Enable(!(m_bWaitForRecording || m_bRecording)); -#endif + // Linux has no FindItem() + #ifdef _WIN32 + // Disable all recording buttons + for(int i = IDB_RECORD + 1; i < (IDB_RECORD + RECORDING_ROWS + 1); i++) + if(ControlsCreated) m_Notebook->FindItem(i)->Enable(!(m_bWaitForRecording || m_bRecording)); + #endif } diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h index ef4c337c3d..0eefff0d47 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigDlg.h @@ -67,21 +67,29 @@ class ConfigDialog : public wxDialog private: DECLARE_EVENT_TABLE(); - - wxButton *m_About, *m_Close, *m_Apply; + + bool ControlsCreated; int Page, BoxW, BoxH; + wxNotebook *m_Notebook; - wxPanel *m_PageEmu, *m_PageReal; + wxPanel *m_Controller[4], *m_PageRecording; + wxButton *m_About, *m_Close, *m_Apply; + wxBoxSizer *m_MainSizer, *m_sMain[4], *m_SizePadding[4],*m_SizeExtensionsPadding[4], *m_SizeBasicGeneral[4], *sRecordingMain, *m_HorizControllers[4], *m_TiltHoriz[4]; + wxStaticBoxSizer *m_SizeBasic[4], *m_SizeExtensions[4], *m_gTilt[4], *m_gJoyname[4]; - bool ControlsCreated; + wxCheckBox *m_SidewaysDPad[4], *m_Joyattach[4]; // Emulated Wiimote settings + wxCheckBox *m_WideScreen[4]; + wxCheckBox *m_NunchuckConnected[4], *m_ClassicControllerConnected[4]; + wxComboBox *m_TiltCombo[4], *m_TiltComboRange[4], *m_Joyname[4]; + wxStaticText *m_TiltText[4]; - wxCheckBox *m_SidewaysDPad; // Emulated Wiimote settings - wxCheckBox *m_WideScreen; - wxCheckBox *m_NunchuckConnected, *m_ClassicControllerConnected; - - wxCheckBox *m_ConnectRealWiimote, *m_UseRealWiimote, *m_UpdateMeters; // Real Wiimote settings + wxCheckBox *m_ConnectRealWiimote[4], *m_UseRealWiimote[4], *m_UpdateMeters; // Real Wiimote settings wxChoice *m_AccNeutralChoice[3], *m_AccNunNeutralChoice[3]; - //static const int RECORDING_ROWS = 15; + wxPanel *m_pInStatus[4], *m_pRightStatus[4]; + wxStaticBitmap *m_bmpDot[4], *m_bmpSquare[4], *m_bmpDotRight[4], *m_bmpSquareRight[4]; + wxStaticBoxSizer *m_gAnalogLeft[4], *m_gAnalogRight[4]; + wxBitmap CreateBitmapDot(), CreateBitmap(); + wxButton * m_RecordButton[RECORDING_ROWS + 1]; wxChoice * m_RecordHotKey[RECORDING_ROWS + 1]; wxTextCtrl * m_RecordText[RECORDING_ROWS + 1]; @@ -109,13 +117,12 @@ class ConfigDialog : public wxDialog ID_ABOUTOGL, IDTM_EXIT, IDTM_UPDATE, IDTM_SHUTDOWN, IDTM_UPDATEA, // Timer - ID_NOTEBOOK, - ID_PAGEEMU, - ID_PAGEREAL, + ID_NOTEBOOK, ID_CONTROLLERPAGE1, ID_CONTROLLERPAGE2, ID_CONTROLLERPAGE3, ID_CONTROLLERPAGE4, ID_PAGE_RECORDING, ID_SIDEWAYSDPAD, // Emulated ID_WIDESCREEN, ID_NUNCHUCKCONNECTED, ID_CLASSICCONTROLLERCONNECTED, + IDC_JOYNAME, IDC_JOYATTACH, ID_TILT_COMBO, ID_TILT_CHECK, // Real ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS, ID_NEUTRAL_CHOICE, @@ -126,6 +133,7 @@ class ConfigDialog : public wxDialog void OnClose(wxCloseEvent& event); void CreateGUIControls(); + void CreateGUIControlsRecording(); void AboutClick(wxCommandEvent& event); void DoConnectReal(); // Real diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp new file mode 100644 index 0000000000..1961cbce4c --- /dev/null +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecording.cpp @@ -0,0 +1,530 @@ +// 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 "Common.h" // for u16 +#include "CommonTypes.h" // for u16 +#include "IniFile.h" +#include "Timer.h" + +#include "wiimote_real.h" // Local +#include "wiimote_hid.h" +#include "main.h" +#include "ConfigDlg.h" +#include "Config.h" +#include "EmuMain.h" // for LoadRecordedMovements() +#include "EmuSubroutines.h" // for WmRequestStatus +////////////////////////////////////// + + + +void ConfigDialog::LoadFile() +{ + Console::Print("LoadFile\n"); + + IniFile file; + file.Load("WiimoteMovement.ini"); + + for(int i = 1; i < (RECORDING_ROWS + 1); i++) + { + // Get row name + std::string SaveName = StringFromFormat("Recording%i", i); + + // HotKey + int TmpRecordHotKey; file.Get(SaveName.c_str(), "HotKey", &TmpRecordHotKey, -1); + m_RecordHotKey[i]->SetSelection(TmpRecordHotKey); + + // Movement name + std::string TmpMovementName; file.Get(SaveName.c_str(), "MovementName", &TmpMovementName, ""); + m_RecordText[i]->SetValue(wxString::FromAscii(TmpMovementName.c_str())); + + // Game name + 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) + m_RecordSpeed[i]->SetValue(wxString::Format(wxT("%i"), TmpRecordSpeed)); + else + m_RecordSpeed[i]->SetValue(wxT("")); + + // Playback speed (currently always saved directly after a recording) + int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1); + m_RecordPlayBackSpeed[i]->SetSelection(TmpPlaybackSpeed); + } +} +void ConfigDialog::SaveFile() +{ + Console::Print("SaveFile\n"); + + IniFile file; + file.Load("WiimoteMovement.ini"); + + for(int i = 1; i < (RECORDING_ROWS + 1); i++) + { + // Get row name + std::string SaveName = StringFromFormat("Recording%i", i); + + // HotKey + file.Set(SaveName.c_str(), "HotKey", m_RecordHotKey[i]->GetSelection()); + + // Movement name + file.Set(SaveName.c_str(), "MovementName", m_RecordText[i]->GetValue().c_str()); + + // Game name + file.Set(SaveName.c_str(), "GameName", m_RecordGameText[i]->GetValue().c_str()); + + // Recording speed (currently always saved directly after a recording) + /* + wxString TmpRecordSpeed = m_RecordSpeed[i]->GetValue(); + if(TmpRecordSpeed.length() > 0) + int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", TmpRecordSpeed); + else + int TmpRecordSpeed; file.Set(SaveName.c_str(), "RecordingSpeed", "-1"); + */ + + // Playback speed (currently always saved directly after a recording) + file.Set(SaveName.c_str(), "PlaybackSpeed", m_RecordPlayBackSpeed[i]->GetSelection()); + } + + file.Save("WiimoteMovement.ini"); +} +///////////////////////////// + + + + + +///////////////////////////////////////////////////////////////////////// +// Create GUI +// ------------ +void ConfigDialog::CreateGUIControlsRecording() +{ + //////////////////////////////////////////////////////////////////////////////// + // Real Wiimote + // ---------------- + + // --------------------------------------------- + // Status + // ---------------- + wxStaticBoxSizer * sbRealStatus = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Status")); + m_TextUpdateRate = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Update rate: 000 times/s")); + m_UpdateMeters = new wxCheckBox(m_PageRecording, ID_UPDATE_REAL, wxT("Update gauges")); + + m_UpdateMeters->SetValue(g_Config.bUpdateRealWiimote); + + m_UpdateMeters->SetToolTip(wxT( + "You can turn this off when a game is running to avoid a potential slowdown that may come from redrawing the\n" + "configuration screen. Remember that you also need to press '+' on your Wiimote before you can record movements." + )); + + sbRealStatus->Add(m_TextUpdateRate, 0, wxEXPAND | (wxALL), 5); + sbRealStatus->Add(m_UpdateMeters, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxUP), 5); + // ----------------------- + + // --------------------------------------------- + // Wiimote accelerometer neutral values + // ---------------- + wxStaticBoxSizer * sbRealNeutral = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Wiimote neutral")); + wxStaticText * m_TextAccNeutralTarget = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Target: 132 132 159")); + m_TextAccNeutralCurrent = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Current: 000 000 000")); + wxArrayString StrAccNeutral; + for(int i = 0; i < 31; i++) StrAccNeutral.Add(wxString::Format(wxT("%i"), i)); + for(int i = 0; i < 3; i++) m_AccNeutralChoice[i] = new wxChoice(m_PageRecording, ID_NEUTRAL_CHOICE, wxDefaultPosition, wxDefaultSize, StrAccNeutral); + m_AccNeutralChoice[0]->SetSelection(g_Config.iAccNeutralX); + m_AccNeutralChoice[1]->SetSelection(g_Config.iAccNeutralY); + m_AccNeutralChoice[2]->SetSelection(g_Config.iAccNeutralZ); + + wxBoxSizer * sbRealWiimoteNeutralChoices = new wxBoxSizer(wxHORIZONTAL); + sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[0], 0, wxEXPAND | (wxALL), 0); + sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[1], 0, wxEXPAND | (wxLEFT), 2); + sbRealWiimoteNeutralChoices->Add(m_AccNeutralChoice[2], 0, wxEXPAND | (wxLEFT), 2); + + sbRealNeutral->Add(m_TextAccNeutralTarget, 0, wxEXPAND | (wxALL), 5); + sbRealNeutral->Add(m_TextAccNeutralCurrent, 0, wxEXPAND | (wxLEFT | wxRIGHT), 5); + sbRealNeutral->Add(sbRealWiimoteNeutralChoices, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxUP), 5); + + m_TextAccNeutralTarget->SetToolTip(wxT( + "To produce compatible accelerometer recordings that can be shared with other users without problems" + " you have to adjust the Current value to the Target value before you make a recording." + )); + + // Wiimote Status + wxBoxSizer * sbRealWiimoteStatus = new wxBoxSizer(wxHORIZONTAL); + + wxStaticBoxSizer * sbRealBattery = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Battery")); + wxStaticBoxSizer * sbRealRoll = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("Roll and Pitch")); + wxStaticBoxSizer * sbRealGForce = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("G-Force")); + wxStaticBoxSizer * sbRealAccel = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("Accelerometer")); + wxStaticBoxSizer * sbRealIR = new wxStaticBoxSizer(wxHORIZONTAL, m_PageRecording, wxT("IR")); + + // Width and height of the gauges + static const int Gw = 35, Gh = 130; + + m_GaugeBattery = new wxGauge( m_PageRecording, wxID_ANY, 100, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeRoll[0] = new wxGauge( m_PageRecording, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeRoll[1] = new wxGauge( m_PageRecording, wxID_ANY, 360, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeGForce[0] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeGForce[1] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeGForce[2] = new wxGauge( m_PageRecording, wxID_ANY, 600, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeAccel[0] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeAccel[1] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + m_GaugeAccel[2] = new wxGauge( m_PageRecording, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH); + + // The text controls + m_TextIR = new wxStaticText(m_PageRecording, 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); + sBoxRoll[1] = new wxBoxSizer(wxVERTICAL); + wxBoxSizer * sBoxGForce[3]; + sBoxGForce[0] = new wxBoxSizer(wxVERTICAL); + sBoxGForce[1] = new wxBoxSizer(wxVERTICAL); + sBoxGForce[2] = new wxBoxSizer(wxVERTICAL); + wxBoxSizer * sBoxAccel[3]; + sBoxAccel[0] = new wxBoxSizer(wxVERTICAL); + sBoxAccel[1] = new wxBoxSizer(wxVERTICAL); + sBoxAccel[2] = new wxBoxSizer(wxVERTICAL); + + wxStaticText * m_TextBattery = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Batt."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + wxStaticText * m_TextRoll = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Roll"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + wxStaticText * m_TextPitch = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Pitch"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + wxStaticText *m_TextX[2], *m_TextY[2], *m_TextZ[2]; + m_TextX[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextX[1] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + m_TextY[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextY[1] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + m_TextZ[0] = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextZ[1] = new wxStaticText(m_PageRecording, 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); + sBoxRoll[1]->Add(m_GaugeRoll[1], 0, wxEXPAND | (wxALL), 5); sBoxRoll[1]->Add(m_TextPitch, 0, wxEXPAND | (wxALL), 0); + + sBoxGForce[0]->Add(m_GaugeGForce[0], 0, wxEXPAND | (wxALL), 5); sBoxGForce[0]->Add(m_TextX[0], 0, wxEXPAND | (wxALL), 0); + sBoxGForce[1]->Add(m_GaugeGForce[1], 0, wxEXPAND | (wxALL), 5); sBoxGForce[1]->Add(m_TextY[0], 0, wxEXPAND | (wxALL), 0); + sBoxGForce[2]->Add(m_GaugeGForce[2], 0, wxEXPAND | (wxALL), 5); sBoxGForce[2]->Add(m_TextZ[0], 0, wxEXPAND | (wxALL), 0); + + sBoxAccel[0]->Add(m_GaugeAccel[0], 0, wxEXPAND | (wxALL), 5); sBoxAccel[0]->Add(m_TextX[1], 0, wxEXPAND | (wxALL), 0); + sBoxAccel[1]->Add(m_GaugeAccel[1], 0, wxEXPAND | (wxALL), 5); sBoxAccel[1]->Add(m_TextY[1], 0, wxEXPAND | (wxALL), 0); + sBoxAccel[2]->Add(m_GaugeAccel[2], 0, wxEXPAND | (wxALL), 5); sBoxAccel[2]->Add(m_TextZ[1], 0, wxEXPAND | (wxALL), 0); + + sbRealBattery->Add(sBoxBattery, 0, wxEXPAND | (wxALL), 5); + 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.")); + // ========================================== + + + // ==================================================================== + // Record movement + // ---------------- + wxStaticBoxSizer * sbRealRecord = new wxStaticBoxSizer(wxVERTICAL, m_PageRecording, wxT("Record movements")); + + wxArrayString StrHotKey; + for(int i = 0; i < 10; i++) StrHotKey.Add(wxString::Format(wxT("%i"), i)); + StrHotKey.Add(wxT("")); + + wxArrayString StrPlayBackSpeed; + for(int i = 1; i <= 20; i++) StrPlayBackSpeed.Add(wxString::Format(wxT("%i"), i*25)); + + wxBoxSizer * sRealRecord[RECORDING_ROWS + 1]; + + wxStaticText * m_TextRec = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Rec."), wxDefaultPosition, wxSize(80, 15), wxALIGN_CENTRE); + wxStaticText * m_TextHotKey = new wxStaticText(m_PageRecording, wxID_ANY, wxT("HotKey"), wxDefaultPosition, wxSize(40, 15), wxALIGN_CENTRE); + wxStaticText * m_TextMovement = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Movement name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE); + wxStaticText * m_TextGame = new wxStaticText(m_PageRecording, wxID_ANY, wxT("Game name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE); + wxStaticText * m_TextIRBytes = new wxStaticText(m_PageRecording, wxID_ANY, wxT("IR"), wxDefaultPosition, wxSize(20, 15), wxALIGN_CENTRE); + wxStaticText * m_TextRecSped = new wxStaticText(m_PageRecording, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(33, 15), wxALIGN_CENTRE); + wxStaticText * m_TextPlaySpeed = new wxStaticText(m_PageRecording, 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" + "by letting go of 'A'")); + m_TextHotKey->SetToolTip(wxT("The HotKey is Shift + [Number] for Wiimote movements and Ctrl + [Number] for Nunchuck movements")); + m_TextRecSped->SetToolTip(wxT("Recording speed in average measurements per second")); + m_TextPlaySpeed->SetToolTip(wxT( + "Playback speed: A playback speed of 100 means that the playback occurs at the same rate as it was recorded. (You can see the\n" + "current update rate in the Status window above when a game is running.) However, if your framerate is only at 50% of full speed\n" + "you may want to select a playback rate of 50, because then the game might perceive the playback as a full speed playback. (This\n" + "holds if Wiimote_Update() is tied to the framerate, I'm not sure that this is the case. It seemed to vary somewhat with different\n" + "framerates but perhaps not enough to say that it was exactly tied to the framerate.) So until this is better understood you'll have\n" + "to try different playback rates and see which one that works." + )); + + sRealRecord[0] = new wxBoxSizer(wxHORIZONTAL); + sRealRecord[0]->Add(m_TextRec, 0, wxEXPAND | (wxLEFT), 5); + 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); + + for(int i = 1; i < (RECORDING_ROWS + 1); i++) + { + sRealRecord[i] = new wxBoxSizer(wxHORIZONTAL); + m_RecordButton[i] = new wxButton(m_PageRecording, IDB_RECORD + i, wxEmptyString, wxDefaultPosition, wxSize(80, 20), 0, wxDefaultValidator, wxEmptyString); + m_RecordHotKey[i] = new wxChoice(m_PageRecording, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey); + m_RecordText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_TEXT, wxT(""), wxDefaultPosition, wxSize(200, 19)); + m_RecordGameText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_GAMETEXT, wxT(""), wxDefaultPosition, wxSize(200, 19)); + m_RecordIRBytesText[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_IRBYTESTEXT, wxT(""), wxDefaultPosition, wxSize(25, 19)); + m_RecordSpeed[i] = new wxTextCtrl(m_PageRecording, IDT_RECORD_SPEED, wxT(""), wxDefaultPosition, wxSize(30, 19), wxTE_READONLY | wxTE_CENTRE); + m_RecordPlayBackSpeed[i] = new wxChoice(m_PageRecording, 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); + + sbRealRecord->Add(sRealRecord[i], 0, wxEXPAND | (wxTOP), 2); + } + // ========================================== + + + // ---------------------------------------------------------------------- + // Set up sizers + // ---------------- + wxBoxSizer * sRealBasicStatus = new wxBoxSizer(wxHORIZONTAL); + sRealBasicStatus->Add(sbRealStatus, 0, wxEXPAND | (wxLEFT), 5); + sRealBasicStatus->Add(sbRealNeutral, 0, wxEXPAND | (wxLEFT), 5); + + sRecordingMain = new wxBoxSizer(wxVERTICAL); + sRecordingMain->Add(sRealBasicStatus, 0, wxEXPAND | (wxALL), 5); + sRecordingMain->Add(sbRealWiimoteStatus, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + sRecordingMain->Add(sbRealRecord, 0, wxEXPAND | (wxLEFT | wxRIGHT | wxDOWN), 5); + + m_PageRecording->SetSizer(sRecordingMain); +} +///////////////////////////////// + + +///////////////////////////////////////////////////////////////////////// +/* Record movement */ +// ------------ + +void ConfigDialog::ConvertToString() +{ + // Load ini file + IniFile file; + file.Load("WiimoteMovement.ini"); + std::string TmpStr = "", TmpIR = "", TmpTime = ""; + + for (int i = 0; i < m_vRecording.size(); i++) + { + // Write the movement data + TmpStr += StringFromFormat("%02x", m_vRecording.at(i).x); + TmpStr += StringFromFormat("%02x", m_vRecording.at(i).y); + TmpStr += StringFromFormat("%02x", m_vRecording.at(i).z); + if(i < (m_vRecording.size() - 1)) TmpStr += ","; + + // 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 + double Recordings = (double)m_vRecording.size(); + double Time = m_vRecording.at(m_vRecording.size() - 1).Time - m_vRecording.at(0).Time; + int Rate = (int)(Recordings / Time); + + // If time or the number of recordings are zero we set the Rate to zero + 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 + int TmpPlaySpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaySpeed, -1); + if (TmpPlaySpeed == -1) + { + file.Set(SaveName.c_str(), "PlaybackSpeed", 3); + m_RecordPlayBackSpeed[m_iRecordTo]->SetSelection(3); + } + + file.Save("WiimoteMovement.ini"); +} + +// Timeout the recording +void ConfigDialog::Update(wxTimerEvent& WXUNUSED(event)) +{ + m_bWaitForRecording = false; + m_bRecording = false; + m_RecordButton[m_iRecordTo]->SetLabel(wxT("")); + UpdateGUI(); +} + +// One second timeout for another A press +void ConfigDialog::UpdateA(wxTimerEvent& WXUNUSED(event)) +{ + m_bAllowA = true; + Console::Print("A allowed again"); +} + +void ConfigDialog::RecordMovement(wxCommandEvent& event) +{ + m_iRecordTo = event.GetId() - 2000; + + if(WiiMoteReal::g_MotionSensing) + { + // Check if there already is a recording here + if(m_RecordSpeed[m_iRecordTo]->GetLineLength(0) > 0) + { + if(!AskYesNo("Do you want to replace the current recording?")) return; + } + m_RecordButton[m_iRecordTo]->SetLabel(wxT("Hold A")); + } + else + { + m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +")); + // This is for usability purposes, it may not be obvious at all that this must be unchecked + // for the recording to work + for(int i = 0; i < 4; i++) m_UseRealWiimote[i]->SetValue(false); g_Config.bUseRealWiimote = false; + return; + } + + m_bWaitForRecording = true; + m_bAllowA = true; + m_bRecording = false; + + UpdateGUI(); + + m_TimeoutTimer->Start(5000, true); + //m_TimeoutATimer->Start(500, true); +} + +void ConfigDialog::DoRecordA(bool Pressed) +{ + // Return if we are not waiting or recording + if (! (m_bWaitForRecording || m_bRecording)) return; + + // Return if we are waiting but have not pressed A + if (m_bWaitForRecording && !Pressed) return; + + // Return if we are recording but are still pressing A + if (m_bRecording && Pressed) return; + + //m_bAllowA = false; + m_bRecording = Pressed; + + // Start recording, only run this once + if(m_bRecording && m_bWaitForRecording) + { + m_RecordButton[m_iRecordTo]->SetLabel(wxT("Recording...")); + m_vRecording.clear(); // Clear the list + m_TimeoutTimer->Stop(); + m_bWaitForRecording = false; + } + // The recording is done + else + { + m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done")); + Console::Print("Done: %i %i\n", m_bWaitForRecording, m_bRecording); + //m_bAllowA = true; + ConvertToString(); + } + + UpdateGUI(); +} + +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"); + + SRecording Tmp; + Tmp.x = _x; + 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) ) + { + m_bRecording = false; + m_RecordButton[m_iRecordTo]->SetLabel(wxT("Done")); + ConvertToString(); + UpdateGUI(); + } +} +///////////////////////////////// \ No newline at end of file diff --git a/Source/Plugins/Plugin_Wiimote/Src/SConscript b/Source/Plugins/Plugin_Wiimote/Src/SConscript index 5a5650d212..ca5ca92c92 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/SConscript +++ b/Source/Plugins/Plugin_Wiimote/Src/SConscript @@ -18,6 +18,7 @@ files = [ if wmenv['HAVE_WX']: files += [ "ConfigDlg.cpp", + "ConfigRecording.cpp", "Logging.cpp", "FillReport.cpp", ] diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp index 4debd1cc7d..1a8479b1b6 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp @@ -354,21 +354,6 @@ bool IsFocus() #endif } -/* -// We have to -void DecryptData(u8 *_data) -{ - // Clear g_RegExtTmp by copying zeroes to it - memset(WiiMoteEmu::g_RegExtTmpReport, 0, sizeof(WiiMoteEmu::g_RegExtTmp)); - // Write the nunchuck inputs to it. We begin writing at 0x08 - memcpy(WiiMoteEmu::g_RegExtTmpReport + 0x08, data + 17, sizeof(wm_extension)); - // Decrypt it - wiimote_decrypt(&WiiMoteEmu::g_ExtKey, &WiiMoteEmu::g_RegExtTmpReport[0x08], 0x08, 0x06); - // Write it back - memcpy(data + 17, &WiiMoteEmu::g_RegExtTmpReport[0x08], sizeof(wm_extension)); -} -*/ - void ReadDebugging(bool Emu, const void* _pData, int Size) { // @@ -436,6 +421,7 @@ void ReadDebugging(bool Emu, const void* _pData, int Size) Console::Print("Js.Min.y: %i\n", data[7 + 12]); Console::Print("JS.Center.y: %i\n\n", data[7 + 13]); } + break; case WM_WRITE_DATA_REPLY: // 0x22 size = sizeof(wm_acknowledge) - 1;