From 1bf2a7ff9db31b0352739051653d37ee27ec9aab Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 29 Jul 2019 14:54:18 -0700 Subject: [PATCH] Implement Balance Board in movies --- Source/Core/Core/Movie.cpp | 58 +++++++++++++++++++++------- Source/Core/Core/Movie.h | 22 ++++++----- Source/Core/DolphinQt/MainWindow.cpp | 16 +++++--- Source/Core/DolphinQt/MainWindow.h | 2 +- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 5b11ddf72a..11976863e4 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -58,6 +58,7 @@ #include "Core/HW/WiimoteCommon/WiimoteReport.h" #include "Core/HW/WiimoteEmu/Encryption.h" +#include "Core/HW/WiimoteEmu/Extension/BalanceBoard.h" #include "Core/HW/WiimoteEmu/Extension/Classic.h" #include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" #include "Core/HW/WiimoteEmu/ExtensionPort.h" @@ -130,10 +131,8 @@ std::string MovieManager::GetInputDisplay() if (!IsMovieActive()) { m_controllers = {}; - m_wiimotes = {}; - const auto& si = m_system.GetSerialInterface(); - for (int i = 0; i < 4; ++i) + for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i) { if (si.GetDeviceType(i) == SerialInterface::SIDEVICE_GC_GBA_EMULATED) m_controllers[i] = ControllerType::GBA; @@ -141,6 +140,10 @@ std::string MovieManager::GetInputDisplay() m_controllers[i] = ControllerType::GC; else m_controllers[i] = ControllerType::None; + } + m_wiimotes = {}; + for (int i = 0; i < MAX_BBMOTES; ++i) + { m_wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None; } } @@ -148,15 +151,15 @@ std::string MovieManager::GetInputDisplay() std::string input_display; { std::lock_guard guard(m_input_display_lock); - for (int i = 0; i < 4; ++i) + for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i) { if (IsUsingPad(i)) input_display += m_input_display[i] + '\n'; } - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_BBMOTES; ++i) { if (IsUsingWiimote(i)) - input_display += m_input_display[i + 4] + '\n'; + input_display += m_input_display[i + SerialInterface::MAX_SI_CHANNELS] + '\n'; } } return input_display; @@ -475,7 +478,7 @@ void MovieManager::ChangeWiiPads(bool instantly) { WiimoteEnabledArray wiimotes{}; - for (int i = 0; i < MAX_WIIMOTES; ++i) + for (int i = 0; i < MAX_BBMOTES; ++i) { wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None; } @@ -485,7 +488,7 @@ void MovieManager::ChangeWiiPads(bool instantly) return; const auto bt = WiiUtils::GetBluetoothEmuDevice(); - for (int i = 0; i < MAX_WIIMOTES; ++i) + for (int i = 0; i < MAX_BBMOTES; ++i) { const bool is_using_wiimote = IsUsingWiimote(i); @@ -676,7 +679,8 @@ static std::string GenerateInputDisplayString(ControllerState padState, int cont static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportBuilder& rpt, ExtensionNumber ext, const EncryptionKey& key) { - std::string display_str = fmt::format("R{}:", remoteID + 1); + std::string display_str = + (remoteID == WIIMOTE_BALANCE_BOARD ? "BB:" : fmt::format("R{}:", remoteID + 1)); if (rpt.HasCore()) { @@ -797,6 +801,21 @@ static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportB display_str += Analog2DToString(right_stick.x, right_stick.y, " R-ANA", 31); } + // Balance board + if (rpt.HasExt() && ext == ExtensionNumber::BALANCE_BOARD) + { + const u8* const extData = rpt.GetExtDataPtr(); + + BalanceBoardExt::DataFormat bb; + memcpy(&bb, extData, sizeof(bb)); + key.Decrypt((u8*)&bb, 0, sizeof(bb)); + + display_str += Analog1DToString(Common::swap16(bb.top_right), " TR", -1); + display_str += Analog1DToString(Common::swap16(bb.bottom_right), " BR", -1); + display_str += Analog1DToString(Common::swap16(bb.top_left), " TL", -1); + display_str += Analog1DToString(Common::swap16(bb.bottom_left), " BL", -1); + } + return display_str; } @@ -864,7 +883,7 @@ void MovieManager::CheckWiimoteStatus(int wiimote, const DataReportBuilder& rpt, std::string display_str = GenerateWiiInputDisplayString(wiimote, rpt, ext, key); std::lock_guard guard(m_input_display_lock); - m_input_display[wiimote + 4] = std::move(display_str); + m_input_display[wiimote + SerialInterface::MAX_SI_CHANNELS] = std::move(display_str); } if (IsRecordingInput()) @@ -886,7 +905,7 @@ void MovieManager::RecordWiimote(int wiimote, const u8* data, u8 size) // NOTE: EmuThread / Host Thread void MovieManager::ReadHeader() { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i) { if (m_temp_header.GBAControllers & (1 << i)) m_controllers[i] = ControllerType::GBA; @@ -894,8 +913,13 @@ void MovieManager::ReadHeader() m_controllers[i] = ControllerType::GC; else m_controllers[i] = ControllerType::None; - m_wiimotes[i] = (m_temp_header.controllers & (1 << (i + 4))) != 0; } + for (int i = 0; i < MAX_WIIMOTES; i++) + { + m_wiimotes[i] = + (m_temp_header.controllers & (1 << (i + SerialInterface::MAX_SI_CHANNELS))) != 0; + } + m_wiimotes[WIIMOTE_BALANCE_BOARD] = m_temp_header.bBalanceBoard; m_recording_start_time = m_temp_header.recordingStartTime; if (m_rerecords < m_temp_header.numRerecords) m_rerecords = m_temp_header.numRerecords; @@ -1374,15 +1398,19 @@ void MovieManager::SaveRecording(const std::string& filename) header.bWii = m_system.IsWii(); header.controllers = 0; header.GBAControllers = 0; - for (int i = 0; i < 4; ++i) + for (int i = 0; i < SerialInterface::MAX_SI_CHANNELS; ++i) { if (IsUsingGBA(i)) header.GBAControllers |= 1 << i; if (IsUsingPad(i)) header.controllers |= 1 << i; - if (IsUsingWiimote(i) && m_system.IsWii()) - header.controllers |= 1 << (i + 4); } + for (int i = 0; i < MAX_WIIMOTES; i++) + { + if (IsUsingWiimote(i) && m_system.IsWii()) + header.controllers |= 1 << (i + SerialInterface::MAX_SI_CHANNELS); + } + header.bBalanceBoard = IsUsingWiimote(WIIMOTE_BALANCE_BOARD); header.bFromSaveState = m_recording_from_save_state; header.frameCount = m_total_frames; diff --git a/Source/Core/Core/Movie.h b/Source/Core/Core/Movie.h index 314123cf51..2d6575120d 100644 --- a/Source/Core/Core/Movie.h +++ b/Source/Core/Core/Movie.h @@ -12,6 +12,8 @@ #include #include "Common/CommonTypes.h" +#include "Core/HW/SI/SI.h" +#include "Core/HW/Wiimote.h" struct BootParameters; @@ -50,8 +52,8 @@ enum class ControllerType GC, GBA, }; -using ControllerTypeArray = std::array; -using WiimoteEnabledArray = std::array; +using ControllerTypeArray = std::array; +using WiimoteEnabledArray = std::array; // GameCube Controller State #pragma pack(push, 1) @@ -130,10 +132,11 @@ struct DTMHeader u8 reserved3; bool bFollowBranch; bool bUseFMA; - u8 GBAControllers; // GBA Controllers plugged in (the bits are ports 1-4) - bool bWidescreen; // true indicates SYSCONF aspect ratio is 16:9, false for 4:3 - u8 countryCode; // SYSCONF country code - std::array reserved; // Padding for any new config options + u8 GBAControllers; // GBA Controllers plugged in (the bits are ports 1-4) + bool bWidescreen; // true indicates SYSCONF aspect ratio is 16:9, false for 4:3 + u8 countryCode; // SYSCONF country code + bool bBalanceBoard; + std::array reserved; // Padding for any new config options std::array discChange; // Name of iso file to switch to, for two disc games. std::array revision; // Git hash u32 DSPiromHash; @@ -237,8 +240,8 @@ private: u32 m_rerecords = 0; PlayMode m_play_mode = PlayMode::None; - std::array m_controllers{}; - std::array m_wiimotes{}; + ControllerTypeArray m_controllers{}; + WiimoteEnabledArray m_wiimotes{}; ControllerState m_pad_state{}; DTMHeader m_temp_header{}; std::vector m_temp_input; @@ -273,7 +276,8 @@ private: // m_input_display is used by both CPU and GPU (is mutable). std::mutex m_input_display_lock; - std::array m_input_display; + std::array(SerialInterface::MAX_SI_CHANNELS) + MAX_BBMOTES> + m_input_display; Core::System& m_system; }; diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 93ad16a59e..6ae1332051 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -350,12 +350,13 @@ MainWindow::~MainWindow() delete m_render_widget; delete m_netplay_dialog; - for (int i = 0; i < 4; i++) + for (int i = 0; i < num_gc_controllers; i++) { delete m_gc_tas_input_windows[i]; delete m_gba_tas_input_windows[i]; - delete m_wii_tas_input_windows[i]; } + for (int i = 0; i < num_wii_controllers; i++) + delete m_wii_tas_input_windows[i]; ShutdownControllers(); @@ -458,12 +459,13 @@ void MainWindow::CreateComponents() m_render_widget = new RenderWidget; m_stack = new QStackedWidget(this); - for (int i = 0; i < 4; i++) + for (int i = 0; i < num_gc_controllers; i++) { m_gc_tas_input_windows[i] = new GCTASInputWindow(nullptr, i); m_gba_tas_input_windows[i] = new GBATASInputWindow(nullptr, i); - m_wii_tas_input_windows[i] = new WiiTASInputWindow(nullptr, i); } + for (int i = 0; i < num_wii_controllers; i++) + m_wii_tas_input_windows[i] = new WiiTASInputWindow(nullptr, i); m_jit_widget = new JITWidget(m_system, this); m_log_widget = new LogWidget(this); @@ -1873,7 +1875,7 @@ void MainWindow::OnStartRecording() Movie::ControllerTypeArray controllers{}; Movie::WiimoteEnabledArray wiimotes{}; - for (int i = 0; i < 4; i++) + for (int i = 0; i < num_gc_controllers; i++) { const SerialInterface::SIDevices si_device = Config::Get(Config::GetInfoForSIDevice(i)); if (si_device == SerialInterface::SIDEVICE_GC_GBA_EMULATED) @@ -1882,6 +1884,10 @@ void MainWindow::OnStartRecording() controllers[i] = Movie::ControllerType::GC; else controllers[i] = Movie::ControllerType::None; + } + + for (int i = 0; i < num_wii_controllers; i++) + { wiimotes[i] = Config::Get(Config::GetInfoForWiimoteSource(i)) != WiimoteSource::None; } diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index f9f0f1c95d..e63f1ab461 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -255,7 +255,7 @@ private: static constexpr int num_gc_controllers = 4; std::array m_gc_tas_input_windows{}; std::array m_gba_tas_input_windows{}; - static constexpr int num_wii_controllers = 4; + static constexpr int num_wii_controllers = 5; std::array m_wii_tas_input_windows{}; #ifdef USE_RETRO_ACHIEVEMENTS