Core/Movie: Make DTM Wii Remote data use SerializedWiimoteState.

This commit is contained in:
Jordan Woyak 2025-02-12 21:22:45 -06:00
parent c770e7c276
commit 83d4249838
5 changed files with 183 additions and 212 deletions

View File

@ -17,13 +17,10 @@
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/MathUtil.h" #include "Common/MathUtil.h"
#include "Common/MsgHandler.h"
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/HW/Wiimote.h" #include "Core/HW/Wiimote.h"
#include "Core/Movie.h"
#include "Core/System.h"
#include "Core/HW/WiimoteCommon/WiimoteConstants.h" #include "Core/HW/WiimoteCommon/WiimoteConstants.h"
#include "Core/HW/WiimoteCommon/WiimoteHid.h" #include "Core/HW/WiimoteCommon/WiimoteHid.h"
@ -39,8 +36,6 @@
#include "Core/HW/WiimoteEmu/Extension/Turntable.h" #include "Core/HW/WiimoteEmu/Extension/Turntable.h"
#include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h" #include "Core/HW/WiimoteEmu/Extension/UDrawTablet.h"
#include "InputCommon/ControllerEmu/Control/Input.h"
#include "InputCommon/ControllerEmu/Control/Output.h"
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" #include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
#include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h"
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
@ -589,9 +584,6 @@ void Wiimote::Update(const WiimoteEmu::DesiredWiimoteState& target_state)
void Wiimote::SendDataReport(const DesiredWiimoteState& target_state) void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
{ {
auto& movie = Core::System::GetInstance().GetMovie();
movie.SetPolledDevice();
if (InputReportID::ReportDisabled == m_reporting_mode) if (InputReportID::ReportDisabled == m_reporting_mode)
{ {
// The wiimote is in this disabled after an extension change. // The wiimote is in this disabled after an extension change.
@ -607,14 +599,6 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
DataReportBuilder rpt_builder(m_reporting_mode); DataReportBuilder rpt_builder(m_reporting_mode);
if (movie.IsPlayingInput() && movie.PlayWiimote(m_bt_device_index, rpt_builder,
m_active_extension, GetExtensionEncryptionKey()))
{
// Update buttons in status struct from movie:
rpt_builder.GetCoreData(&m_status.buttons);
}
else
{
// Core buttons: // Core buttons:
if (rpt_builder.HasCore()) if (rpt_builder.HasCore())
{ {
@ -675,10 +659,6 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
std::fill_n(ext_data, ext_size, u8(0xff)); std::fill_n(ext_data, ext_size, u8(0xff));
} }
} }
}
movie.CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension,
GetExtensionEncryptionKey());
// Send the report: // Send the report:
InterruptDataInputCallback(rpt_builder.GetDataPtr(), rpt_builder.GetDataSize()); InterruptDataInputCallback(rpt_builder.GetDataPtr(), rpt_builder.GetDataSize());
@ -741,10 +721,11 @@ void Wiimote::LoadDefaults(const ControllerInterface& ciface)
// B // B
m_buttons->SetControlExpression(1, "`Click 1`"); m_buttons->SetControlExpression(1, "`Click 1`");
#endif #endif
m_buttons->SetControlExpression(2, "`1`"); // 1 // 1 2 - +
m_buttons->SetControlExpression(3, "`2`"); // 2 m_buttons->SetControlExpression(2, "`1`");
m_buttons->SetControlExpression(4, "Q"); // - m_buttons->SetControlExpression(3, "`2`");
m_buttons->SetControlExpression(5, "E"); // + m_buttons->SetControlExpression(4, "Q");
m_buttons->SetControlExpression(5, "E");
#ifdef _WIN32 #ifdef _WIN32
m_buttons->SetControlExpression(6, "RETURN"); // Home m_buttons->SetControlExpression(6, "RETURN"); // Home

View File

@ -11,8 +11,6 @@
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Common/NandPaths.h"
#include "Common/StringUtil.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
#include "Core/Debugger/Debugger_SymbolMap.h" #include "Core/Debugger/Debugger_SymbolMap.h"
@ -22,6 +20,7 @@
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h" #include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
#include "Core/IOS/Device.h" #include "Core/IOS/Device.h"
#include "Core/IOS/IOS.h" #include "Core/IOS/IOS.h"
#include "Core/Movie.h"
#include "Core/NetPlayClient.h" #include "Core/NetPlayClient.h"
#include "Core/NetPlayProto.h" #include "Core/NetPlayProto.h"
#include "Core/SysConf.h" #include "Core/SysConf.h"
@ -390,6 +389,16 @@ void BluetoothEmuDevice::Update()
} }
} }
auto& movie = Core::System::GetInstance().GetMovie();
for (int i = 0; i != MAX_WIIMOTES; ++i)
{
if (next_call[i] == WiimoteDevice::NextUpdateInputCall::None)
continue;
movie.PlayWiimote(i, &wiimote_states[i]);
movie.CheckWiimoteStatus(i, wiimote_states[i]);
}
for (size_t i = 0; i < m_wiimotes.size(); ++i) for (size_t i = 0; i < m_wiimotes.size(); ++i)
m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]); m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]);

View File

@ -292,9 +292,8 @@ void WiimoteDevice::SetSource(WiimoteCommon::HIDWiimote* hid_source)
if (m_hid_source) if (m_hid_source)
{ {
m_hid_source->SetInterruptCallback(std::bind(&WiimoteDevice::InterruptDataInputCallback, this, m_hid_source->SetInterruptCallback(
std::placeholders::_1, std::placeholders::_2, std::bind_front(&WiimoteDevice::InterruptDataInputCallback, this));
std::placeholders::_3));
Activate(true); Activate(true);
} }
} }

View File

@ -12,7 +12,6 @@
#include <mbedtls/config.h> #include <mbedtls/config.h>
#include <mbedtls/md.h> #include <mbedtls/md.h>
#include <mutex> #include <mutex>
#include <sstream>
#include <thread> #include <thread>
#include <utility> #include <utility>
#include <variant> #include <variant>
@ -32,13 +31,13 @@
#include "Common/NandPaths.h" #include "Common/NandPaths.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/Timer.h" #include "Common/Timer.h"
#include "Common/VariantUtil.h"
#include "Common/Version.h" #include "Common/Version.h"
#include "Core/AchievementManager.h" #include "Core/AchievementManager.h"
#include "Core/Boot/Boot.h" #include "Core/Boot/Boot.h"
#include "Core/Config/AchievementSettings.h" #include "Core/Config/AchievementSettings.h"
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/WiimoteSettings.h" #include "Core/Config/WiimoteSettings.h"
#include "Core/ConfigLoaders/MovieConfigLoader.h" #include "Core/ConfigLoaders/MovieConfigLoader.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
@ -54,14 +53,10 @@
#include "Core/HW/SI/SI.h" #include "Core/HW/SI/SI.h"
#include "Core/HW/SI/SI_Device.h" #include "Core/HW/SI/SI_Device.h"
#include "Core/HW/Wiimote.h" #include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteCommon/DataReport.h"
#include "Core/HW/WiimoteCommon/WiimoteReport.h" #include "Core/HW/WiimoteCommon/WiimoteReport.h"
#include "Core/HW/WiimoteEmu/Encryption.h"
#include "Core/HW/WiimoteEmu/Extension/Classic.h" #include "Core/HW/WiimoteEmu/Extension/Classic.h"
#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" #include "Core/HW/WiimoteEmu/Extension/Nunchuk.h"
#include "Core/HW/WiimoteEmu/ExtensionPort.h" #include "Core/HW/WiimoteEmu/ExtensionPort.h"
#include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h"
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
#include "Core/NetPlayProto.h" #include "Core/NetPlayProto.h"
@ -69,16 +64,11 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/WiiUtils.h" #include "Core/WiiUtils.h"
#include "DiscIO/Enums.h"
#include "InputCommon/GCPadStatus.h" #include "InputCommon/GCPadStatus.h"
#include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
// The chunk to allocate movie data in multiples of.
#define DTM_BASE_LENGTH (1024)
namespace Movie namespace Movie
{ {
using namespace WiimoteCommon; using namespace WiimoteCommon;
@ -554,7 +544,7 @@ bool MovieManager::BeginRecordingInput(const ControllerTypeArray& controllers,
if (!Core::IsRunning(m_system)) if (!Core::IsRunning(m_system))
{ {
// This will also reset the Wiimotes for GameCube games, but that shouldn't do anything // This will also reset the Wiimotes for GameCube games, but that shouldn't do anything
Wiimote::ResetAllWiimotes(); ::Wiimote::ResetAllWiimotes();
} }
m_play_mode = PlayMode::Recording; m_play_mode = PlayMode::Recording;
@ -673,16 +663,13 @@ static std::string GenerateInputDisplayString(ControllerState padState, int cont
} }
// NOTE: CPU Thread // NOTE: CPU Thread
static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportBuilder& rpt, static std::string GenerateWiiInputDisplayString(int index, const DesiredWiimoteState& state)
ExtensionNumber ext, const EncryptionKey& key)
{ {
std::string display_str = fmt::format("R{}:", remoteID + 1); std::string display_str = fmt::format("R{}:", index + 1);
if (rpt.HasCore()) const auto& buttons = state.buttons;
if (buttons.hex & WiimoteCommon::ButtonData::BUTTON_MASK)
{ {
ButtonData buttons;
rpt.GetCoreData(&buttons);
if (buttons.left) if (buttons.left)
display_str += " LEFT"; display_str += " LEFT";
if (buttons.right) if (buttons.right)
@ -707,94 +694,83 @@ static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportB
display_str += " HOME"; display_str += " HOME";
} }
if (rpt.HasAccel()) if (state.acceleration != state.DEFAULT_ACCELERATION)
{ {
AccelData accel_data; const AccelData& accel_data = state.acceleration;
rpt.GetAccelData(&accel_data);
// FYI: This will only print partial data for interleaved reports.
display_str += display_str +=
fmt::format(" ACC:{},{},{}", accel_data.value.x, accel_data.value.y, accel_data.value.z); fmt::format(" ACC:{},{},{}", accel_data.value.x, accel_data.value.y, accel_data.value.z);
} }
if (rpt.HasIR()) if (state.camera_points != state.DEFAULT_CAMERA)
{ {
const u8* const ir_data = rpt.GetIRDataPtr(); display_str += " IR:";
for (auto& point : state.camera_points)
// TODO: This does not handle the different IR formats. {
if (point.size == 0xff)
const u16 x = ir_data[0] | ((ir_data[2] >> 4 & 0x3) << 8); display_str += "_,";
const u16 y = ir_data[1] | ((ir_data[2] >> 6 & 0x3) << 8); else
display_str += fmt::format(" IR:{},{}", x, y); display_str += fmt::format("{},{},", point.position.x, point.position.y);
}
display_str.pop_back();
} }
// Nunchuk if (state.extension.data.index() != ExtensionNumber::NONE)
if (rpt.HasExt() && ext == ExtensionNumber::NUNCHUK)
{ {
const u8* const extData = rpt.GetExtDataPtr(); const auto ext_visitor = overloaded{
[&](const Nunchuk::DataFormat& nunchuk) {
Nunchuk::DataFormat nunchuk; const auto bt = nunchuk.GetButtons();
memcpy(&nunchuk, extData, sizeof(nunchuk)); if (bt & Nunchuk::BUTTON_C)
key.Decrypt((u8*)&nunchuk, 0, sizeof(nunchuk));
nunchuk.bt.hex = nunchuk.bt.hex ^ 0x3;
const std::string accel = fmt::format(" N-ACC:{},{},{}", nunchuk.GetAccelX(),
nunchuk.GetAccelY(), nunchuk.GetAccelZ());
if (nunchuk.bt.c)
display_str += " C"; display_str += " C";
if (nunchuk.bt.z) if (bt & Nunchuk::BUTTON_Z)
display_str += " Z"; display_str += " Z";
display_str += accel; display_str += fmt::format(" N-ACC:{},{},{}", nunchuk.GetAccelX(), nunchuk.GetAccelY(),
nunchuk.GetAccelZ());
display_str += Analog2DToString(nunchuk.jx, nunchuk.jy, " ANA"); display_str += Analog2DToString(nunchuk.jx, nunchuk.jy, " ANA");
} },
[&](const Classic::DataFormat& cc) {
// Classic controller const auto bt = cc.GetButtons();
if (rpt.HasExt() && ext == ExtensionNumber::CLASSIC) constexpr std::pair<u16, const char*> named_buttons[] = {
{Classic::PAD_LEFT, "LEFT"}, {Classic::PAD_RIGHT, "RIGHT"},
{Classic::PAD_DOWN, "DOWN"}, {Classic::PAD_UP, "UP"},
{Classic::BUTTON_A, "A"}, {Classic::BUTTON_B, "B"},
{Classic::BUTTON_X, "X"}, {Classic::BUTTON_Y, "Y"},
{Classic::BUTTON_ZL, "ZL"}, {Classic::BUTTON_ZR, "ZR"},
{Classic::BUTTON_PLUS, "+"}, {Classic::BUTTON_MINUS, "-"},
{Classic::BUTTON_HOME, "HOME"},
};
for (auto& [value, name] : named_buttons)
{ {
const u8* const extData = rpt.GetExtDataPtr(); if (bt & value)
{
Classic::DataFormat cc; display_str += ' ';
memcpy(&cc, extData, sizeof(cc)); display_str += name;
key.Decrypt((u8*)&cc, 0, sizeof(cc)); }
cc.bt.hex = cc.bt.hex ^ 0xFFFF; }
constexpr auto trigger_max = (1 << Classic::TRIGGER_BITS) - 1;
if (cc.bt.dpad_left) display_str += Analog1DToString(cc.GetLeftTrigger().value, " L", trigger_max);
display_str += " LEFT"; display_str += Analog1DToString(cc.GetRightTrigger().value, " R", trigger_max);
if (cc.bt.dpad_right)
display_str += " RIGHT";
if (cc.bt.dpad_down)
display_str += " DOWN";
if (cc.bt.dpad_up)
display_str += " UP";
if (cc.bt.a)
display_str += " A";
if (cc.bt.b)
display_str += " B";
if (cc.bt.x)
display_str += " X";
if (cc.bt.y)
display_str += " Y";
if (cc.bt.zl)
display_str += " ZL";
if (cc.bt.zr)
display_str += " ZR";
if (cc.bt.plus)
display_str += " +";
if (cc.bt.minus)
display_str += " -";
if (cc.bt.home)
display_str += " HOME";
display_str += Analog1DToString(cc.GetLeftTrigger().value, " L", 31);
display_str += Analog1DToString(cc.GetRightTrigger().value, " R", 31);
constexpr auto lstick_max = (1 << Classic::LEFT_STICK_BITS) - 1;
const auto left_stick = cc.GetLeftStick().value; const auto left_stick = cc.GetLeftStick().value;
display_str += Analog2DToString(left_stick.x, left_stick.y, " ANA", 63); display_str += Analog2DToString(left_stick.x, left_stick.y, " ANA", lstick_max);
constexpr auto rstick_max = (1 << Classic::RIGHT_STICK_BITS) - 1;
const auto right_stick = cc.GetRightStick().value; const auto right_stick = cc.GetRightStick().value;
display_str += Analog2DToString(right_stick.x, right_stick.y, " R-ANA", 31); display_str += Analog2DToString(right_stick.x, right_stick.y, " R-ANA", rstick_max);
},
[&](const Guitar::DataFormat&) { display_str += " Guitar"; },
[&](const Drums::DesiredState&) { display_str += " Drums"; },
[&](const Turntable::DataFormat&) { display_str += " Turntable"; },
[&](const UDrawTablet::DataFormat&) { display_str += " UDraw"; },
[&](const DrawsomeTablet::DataFormat&) { display_str += " Drawsome"; },
[&](const TaTaCon::DataFormat&) { display_str += " TaTaCon"; },
[&](const Shinkansen::DesiredState&) { display_str += " Shinkansen"; },
[](const auto& arg) {
static_assert(std::is_same_v<std::monostate, std::decay_t<decltype(arg)>>,
"unimplemented extension");
},
};
std::visit(ext_visitor, state.extension.data);
} }
return display_str; return display_str;
@ -857,29 +833,32 @@ void MovieManager::RecordInput(const GCPadStatus* PadStatus, int controllerID)
} }
// NOTE: CPU Thread // NOTE: CPU Thread
void MovieManager::CheckWiimoteStatus(int wiimote, const DataReportBuilder& rpt, void MovieManager::CheckWiimoteStatus(int wiimote, const DesiredWiimoteState& desired_state)
ExtensionNumber ext, const EncryptionKey& key)
{ {
SetPolledDevice();
{ {
std::string display_str = GenerateWiiInputDisplayString(wiimote, rpt, ext, key); std::string display_str = GenerateWiiInputDisplayString(wiimote, desired_state);
std::lock_guard guard(m_input_display_lock); std::lock_guard guard(m_input_display_lock);
m_input_display[wiimote + 4] = std::move(display_str); m_input_display[wiimote + 4] = std::move(display_str);
} }
if (IsRecordingInput()) if (IsRecordingInput())
RecordWiimote(wiimote, rpt.GetDataPtr(), rpt.GetDataSize()); RecordWiimote(wiimote, SerializeDesiredState(desired_state));
} }
void MovieManager::RecordWiimote(int wiimote, const u8* data, u8 size) void MovieManager::RecordWiimote(int wiimote, const SerializedWiimoteState& serialized_state)
{ {
if (!IsRecordingInput() || !IsUsingWiimote(wiimote)) if (!IsRecordingInput() || !IsUsingWiimote(wiimote))
return; return;
InputUpdate(); InputUpdate();
const u8 size = serialized_state.length;
m_temp_input.resize(m_current_byte + size + 1); m_temp_input.resize(m_current_byte + size + 1);
m_temp_input[m_current_byte++] = size; m_temp_input[m_current_byte++] = size;
memcpy(&m_temp_input[m_current_byte], data, size); std::copy_n(serialized_state.data.data(), size, m_temp_input.data() + m_current_byte);
m_current_byte += size; m_current_byte += size;
} }
@ -955,7 +934,7 @@ bool MovieManager::PlayInput(const std::string& movie_path,
m_play_mode = PlayMode::Playing; m_play_mode = PlayMode::Playing;
// Wiimotes cause desync issues if they're not reset before launching the game // Wiimotes cause desync issues if they're not reset before launching the game
Wiimote::ResetAllWiimotes(); ::Wiimote::ResetAllWiimotes();
Core::UpdateWantDeterminism(m_system); Core::UpdateWantDeterminism(m_system);
@ -1275,28 +1254,44 @@ void MovieManager::PlayController(GCPadStatus* PadStatus, int controllerID)
} }
// NOTE: CPU Thread // NOTE: CPU Thread
bool MovieManager::PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt, bool MovieManager::PlayWiimote(int wiimote, DesiredWiimoteState* desired_state)
ExtensionNumber ext, const EncryptionKey& key)
{ {
if (!IsPlayingInput() || !IsUsingWiimote(wiimote) || m_temp_input.empty()) if (!IsPlayingInput() || !IsUsingWiimote(wiimote) || m_temp_input.empty())
return false; return false;
if (m_current_byte > m_temp_input.size()) if (m_current_byte + sizeof(u8) > m_temp_input.size())
{ {
PanicAlertFmtT("Premature movie end in PlayWiimote. {0} > {1}", m_current_byte, PanicAlertFmtT("Premature movie end in PlayWiimote. {0} + 1 > {1}", m_current_byte,
m_temp_input.size()); m_temp_input.size());
EndPlayInput(!m_read_only); EndPlayInput(!m_read_only);
return false; return false;
} }
const u8 size = rpt.GetDataSize(); SerializedWiimoteState serialized;
const u8 sizeInMovie = m_temp_input[m_current_byte]; serialized.length = m_temp_input[m_current_byte];
if (size != sizeInMovie) if (serialized.length > serialized.data.size())
{ {
PanicAlertFmtT( PanicAlertFmtT("Invalid serialized length:{0} in PlayWiimote. byte:{1}", int(serialized.length),
"Fatal desync. Aborting playback. (Error in PlayWiimote: {0} != {1}, byte {2}.){3}", m_current_byte);
sizeInMovie, size, m_current_byte, EndPlayInput(!m_read_only);
return false;
}
++m_current_byte;
if (m_current_byte + serialized.length > m_temp_input.size())
{
PanicAlertFmtT("Premature movie end in PlayWiimote. {0} + {1} > {2}", m_current_byte,
int(serialized.length), m_temp_input.size());
EndPlayInput(!m_read_only);
return false;
}
std::copy_n(m_temp_input.data() + m_current_byte, serialized.length, serialized.data.data());
if (!WiimoteEmu::DeserializeDesiredState(desired_state, serialized))
{
PanicAlertFmtT("Aborting playback. Error in DeserializeDesiredState. byte:{0}{1}",
m_current_byte,
(m_controllers == ControllerTypeArray{}) ? (m_controllers == ControllerTypeArray{}) ?
" Try re-creating the recording with all GameCube controllers " " Try re-creating the recording with all GameCube controllers "
"disabled (in Configure > GameCube > Device Settings)." : "disabled (in Configure > GameCube > Device Settings)." :
@ -1305,20 +1300,8 @@ bool MovieManager::PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rp
return false; return false;
} }
m_current_byte++; m_current_byte += serialized.length;
++m_current_input_count;
if (m_current_byte + size > m_temp_input.size())
{
PanicAlertFmtT("Premature movie end in PlayWiimote. {0} + {1} > {2}", m_current_byte, size,
m_temp_input.size());
EndPlayInput(!m_read_only);
return false;
}
memcpy(rpt.GetDataPtr(), &m_temp_input[m_current_byte], size);
m_current_byte += size;
m_current_input_count++;
CheckInputEnd(); CheckInputEnd();
return true; return true;

View File

@ -12,6 +12,7 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
struct BootParameters; struct BootParameters;
@ -206,21 +207,19 @@ public:
bool BeginRecordingInput(const ControllerTypeArray& controllers, bool BeginRecordingInput(const ControllerTypeArray& controllers,
const WiimoteEnabledArray& wiimotes); const WiimoteEnabledArray& wiimotes);
void RecordInput(const GCPadStatus* PadStatus, int controllerID); void RecordInput(const GCPadStatus* PadStatus, int controllerID);
void RecordWiimote(int wiimote, const u8* data, u8 size); void RecordWiimote(int wiimote, const WiimoteEmu::SerializedWiimoteState& serialized_state);
bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path); bool PlayInput(const std::string& movie_path, std::optional<std::string>* savestate_path);
void LoadInput(const std::string& movie_path); void LoadInput(const std::string& movie_path);
void ReadHeader(); void ReadHeader();
void PlayController(GCPadStatus* PadStatus, int controllerID); void PlayController(GCPadStatus* PadStatus, int controllerID);
bool PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt, bool PlayWiimote(int wiimote, WiimoteEmu::DesiredWiimoteState* desired_state);
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
void EndPlayInput(bool cont); void EndPlayInput(bool cont);
void SaveRecording(const std::string& filename); void SaveRecording(const std::string& filename);
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void Shutdown(); void Shutdown();
void CheckPadStatus(const GCPadStatus* PadStatus, int controllerID); void CheckPadStatus(const GCPadStatus* PadStatus, int controllerID);
void CheckWiimoteStatus(int wiimote, const WiimoteCommon::DataReportBuilder& rpt, void CheckWiimoteStatus(int wiimote, const WiimoteEmu::DesiredWiimoteState& desired_state);
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
std::string GetInputDisplay(); std::string GetInputDisplay();
std::string GetRTCDisplay() const; std::string GetRTCDisplay() const;