mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-10 11:37:43 +01:00
Core/Movie: Make DTM Wii Remote data use SerializedWiimoteState.
This commit is contained in:
parent
c770e7c276
commit
83d4249838
@ -17,13 +17,10 @@
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "Core/HW/WiimoteCommon/WiimoteConstants.h"
|
||||
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
||||
@ -39,8 +36,6 @@
|
||||
#include "Core/HW/WiimoteEmu/Extension/Turntable.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/Buttons.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)
|
||||
{
|
||||
auto& movie = Core::System::GetInstance().GetMovie();
|
||||
movie.SetPolledDevice();
|
||||
|
||||
if (InputReportID::ReportDisabled == m_reporting_mode)
|
||||
{
|
||||
// The wiimote is in this disabled after an extension change.
|
||||
@ -607,78 +599,66 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state)
|
||||
|
||||
DataReportBuilder rpt_builder(m_reporting_mode);
|
||||
|
||||
if (movie.IsPlayingInput() && movie.PlayWiimote(m_bt_device_index, rpt_builder,
|
||||
m_active_extension, GetExtensionEncryptionKey()))
|
||||
// Core buttons:
|
||||
if (rpt_builder.HasCore())
|
||||
{
|
||||
// Update buttons in status struct from movie:
|
||||
rpt_builder.GetCoreData(&m_status.buttons);
|
||||
rpt_builder.SetCoreData(m_status.buttons);
|
||||
}
|
||||
else
|
||||
|
||||
// Acceleration:
|
||||
if (rpt_builder.HasAccel())
|
||||
{
|
||||
// Core buttons:
|
||||
if (rpt_builder.HasCore())
|
||||
rpt_builder.SetAccelData(target_state.acceleration);
|
||||
}
|
||||
|
||||
// IR Camera:
|
||||
if (rpt_builder.HasIR())
|
||||
{
|
||||
// Note: Camera logic currently contains no changing state so we can just update it here.
|
||||
// If that changes this should be moved to Wiimote::Update();
|
||||
m_camera_logic.Update(target_state.camera_points);
|
||||
|
||||
// The real wiimote reads camera data from the i2c bus starting at offset 0x37:
|
||||
const u8 camera_data_offset =
|
||||
CameraLogic::REPORT_DATA_OFFSET + rpt_builder.GetIRDataFormatOffset();
|
||||
|
||||
u8* ir_data = rpt_builder.GetIRDataPtr();
|
||||
const u8 ir_size = rpt_builder.GetIRDataSize();
|
||||
|
||||
if (ir_size != m_i2c_bus.BusRead(CameraLogic::I2C_ADDR, camera_data_offset, ir_size, ir_data))
|
||||
{
|
||||
rpt_builder.SetCoreData(m_status.buttons);
|
||||
}
|
||||
|
||||
// Acceleration:
|
||||
if (rpt_builder.HasAccel())
|
||||
{
|
||||
rpt_builder.SetAccelData(target_state.acceleration);
|
||||
}
|
||||
|
||||
// IR Camera:
|
||||
if (rpt_builder.HasIR())
|
||||
{
|
||||
// Note: Camera logic currently contains no changing state so we can just update it here.
|
||||
// If that changes this should be moved to Wiimote::Update();
|
||||
m_camera_logic.Update(target_state.camera_points);
|
||||
|
||||
// The real wiimote reads camera data from the i2c bus starting at offset 0x37:
|
||||
const u8 camera_data_offset =
|
||||
CameraLogic::REPORT_DATA_OFFSET + rpt_builder.GetIRDataFormatOffset();
|
||||
|
||||
u8* ir_data = rpt_builder.GetIRDataPtr();
|
||||
const u8 ir_size = rpt_builder.GetIRDataSize();
|
||||
|
||||
if (ir_size != m_i2c_bus.BusRead(CameraLogic::I2C_ADDR, camera_data_offset, ir_size, ir_data))
|
||||
{
|
||||
// This happens when IR reporting is enabled but the camera hardware is disabled.
|
||||
// It commonly occurs when changing IR sensitivity.
|
||||
std::fill_n(ir_data, ir_size, u8(0xff));
|
||||
}
|
||||
}
|
||||
|
||||
// Extension port:
|
||||
if (rpt_builder.HasExt())
|
||||
{
|
||||
// Prepare extension input first as motion-plus may read from it.
|
||||
// This currently happens in Wiimote::Update();
|
||||
// TODO: Separate extension input data preparation from Update.
|
||||
// GetActiveExtension()->PrepareInput();
|
||||
|
||||
if (m_is_motion_plus_attached)
|
||||
{
|
||||
// TODO: Make input preparation triggered by bus read.
|
||||
m_motion_plus.PrepareInput(target_state.motion_plus.has_value() ?
|
||||
target_state.motion_plus.value() :
|
||||
MotionPlus::GetDefaultGyroscopeData());
|
||||
}
|
||||
|
||||
u8* ext_data = rpt_builder.GetExtDataPtr();
|
||||
const u8 ext_size = rpt_builder.GetExtDataSize();
|
||||
|
||||
if (ext_size != m_i2c_bus.BusRead(ExtensionPort::REPORT_I2C_SLAVE,
|
||||
ExtensionPort::REPORT_I2C_ADDR, ext_size, ext_data))
|
||||
{
|
||||
// Real wiimote seems to fill with 0xff on failed bus read
|
||||
std::fill_n(ext_data, ext_size, u8(0xff));
|
||||
}
|
||||
// This happens when IR reporting is enabled but the camera hardware is disabled.
|
||||
// It commonly occurs when changing IR sensitivity.
|
||||
std::fill_n(ir_data, ir_size, u8(0xff));
|
||||
}
|
||||
}
|
||||
|
||||
movie.CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension,
|
||||
GetExtensionEncryptionKey());
|
||||
// Extension port:
|
||||
if (rpt_builder.HasExt())
|
||||
{
|
||||
// Prepare extension input first as motion-plus may read from it.
|
||||
// This currently happens in Wiimote::Update();
|
||||
// TODO: Separate extension input data preparation from Update.
|
||||
// GetActiveExtension()->PrepareInput();
|
||||
|
||||
if (m_is_motion_plus_attached)
|
||||
{
|
||||
// TODO: Make input preparation triggered by bus read.
|
||||
m_motion_plus.PrepareInput(target_state.motion_plus.has_value() ?
|
||||
target_state.motion_plus.value() :
|
||||
MotionPlus::GetDefaultGyroscopeData());
|
||||
}
|
||||
|
||||
u8* ext_data = rpt_builder.GetExtDataPtr();
|
||||
const u8 ext_size = rpt_builder.GetExtDataSize();
|
||||
|
||||
if (ext_size != m_i2c_bus.BusRead(ExtensionPort::REPORT_I2C_SLAVE,
|
||||
ExtensionPort::REPORT_I2C_ADDR, ext_size, ext_data))
|
||||
{
|
||||
// Real wiimote seems to fill with 0xff on failed bus read
|
||||
std::fill_n(ext_data, ext_size, u8(0xff));
|
||||
}
|
||||
}
|
||||
|
||||
// Send the report:
|
||||
InterruptDataInputCallback(rpt_builder.GetDataPtr(), rpt_builder.GetDataSize());
|
||||
@ -741,10 +721,11 @@ void Wiimote::LoadDefaults(const ControllerInterface& ciface)
|
||||
// B
|
||||
m_buttons->SetControlExpression(1, "`Click 1`");
|
||||
#endif
|
||||
m_buttons->SetControlExpression(2, "`1`"); // 1
|
||||
m_buttons->SetControlExpression(3, "`2`"); // 2
|
||||
m_buttons->SetControlExpression(4, "Q"); // -
|
||||
m_buttons->SetControlExpression(5, "E"); // +
|
||||
// 1 2 - +
|
||||
m_buttons->SetControlExpression(2, "`1`");
|
||||
m_buttons->SetControlExpression(3, "`2`");
|
||||
m_buttons->SetControlExpression(4, "Q");
|
||||
m_buttons->SetControlExpression(5, "E");
|
||||
|
||||
#ifdef _WIN32
|
||||
m_buttons->SetControlExpression(6, "RETURN"); // Home
|
||||
|
@ -11,8 +11,6 @@
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/NandPaths.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||
@ -22,6 +20,7 @@
|
||||
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
|
||||
#include "Core/IOS/Device.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "Core/NetPlayProto.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)
|
||||
m_wiimotes[i]->UpdateInput(next_call[i], wiimote_states[i]);
|
||||
|
||||
|
@ -292,9 +292,8 @@ void WiimoteDevice::SetSource(WiimoteCommon::HIDWiimote* hid_source)
|
||||
|
||||
if (m_hid_source)
|
||||
{
|
||||
m_hid_source->SetInterruptCallback(std::bind(&WiimoteDevice::InterruptDataInputCallback, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3));
|
||||
m_hid_source->SetInterruptCallback(
|
||||
std::bind_front(&WiimoteDevice::InterruptDataInputCallback, this));
|
||||
Activate(true);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <mbedtls/config.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
@ -32,13 +31,13 @@
|
||||
#include "Common/NandPaths.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Timer.h"
|
||||
#include "Common/VariantUtil.h"
|
||||
#include "Common/Version.h"
|
||||
|
||||
#include "Core/AchievementManager.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Config/AchievementSettings.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/SYSCONFSettings.h"
|
||||
#include "Core/Config/WiimoteSettings.h"
|
||||
#include "Core/ConfigLoaders/MovieConfigLoader.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
@ -54,14 +53,10 @@
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/SI/SI_Device.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/HW/WiimoteCommon/DataReport.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/Nunchuk.h"
|
||||
#include "Core/HW/WiimoteEmu/ExtensionPort.h"
|
||||
|
||||
#include "Core/IOS/USB/Bluetooth/BTEmu.h"
|
||||
#include "Core/IOS/USB/Bluetooth/WiimoteDevice.h"
|
||||
#include "Core/NetPlayProto.h"
|
||||
@ -69,16 +64,11 @@
|
||||
#include "Core/System.h"
|
||||
#include "Core/WiiUtils.h"
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
// The chunk to allocate movie data in multiples of.
|
||||
#define DTM_BASE_LENGTH (1024)
|
||||
|
||||
namespace Movie
|
||||
{
|
||||
using namespace WiimoteCommon;
|
||||
@ -554,7 +544,7 @@ bool MovieManager::BeginRecordingInput(const ControllerTypeArray& controllers,
|
||||
if (!Core::IsRunning(m_system))
|
||||
{
|
||||
// This will also reset the Wiimotes for GameCube games, but that shouldn't do anything
|
||||
Wiimote::ResetAllWiimotes();
|
||||
::Wiimote::ResetAllWiimotes();
|
||||
}
|
||||
|
||||
m_play_mode = PlayMode::Recording;
|
||||
@ -673,16 +663,13 @@ static std::string GenerateInputDisplayString(ControllerState padState, int cont
|
||||
}
|
||||
|
||||
// NOTE: CPU Thread
|
||||
static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportBuilder& rpt,
|
||||
ExtensionNumber ext, const EncryptionKey& key)
|
||||
static std::string GenerateWiiInputDisplayString(int index, const DesiredWiimoteState& state)
|
||||
{
|
||||
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)
|
||||
display_str += " LEFT";
|
||||
if (buttons.right)
|
||||
@ -707,94 +694,83 @@ static std::string GenerateWiiInputDisplayString(int remoteID, const DataReportB
|
||||
display_str += " HOME";
|
||||
}
|
||||
|
||||
if (rpt.HasAccel())
|
||||
if (state.acceleration != state.DEFAULT_ACCELERATION)
|
||||
{
|
||||
AccelData accel_data;
|
||||
rpt.GetAccelData(&accel_data);
|
||||
|
||||
// FYI: This will only print partial data for interleaved reports.
|
||||
|
||||
const AccelData& accel_data = state.acceleration;
|
||||
display_str +=
|
||||
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();
|
||||
|
||||
// TODO: This does not handle the different IR formats.
|
||||
|
||||
const u16 x = ir_data[0] | ((ir_data[2] >> 4 & 0x3) << 8);
|
||||
const u16 y = ir_data[1] | ((ir_data[2] >> 6 & 0x3) << 8);
|
||||
display_str += fmt::format(" IR:{},{}", x, y);
|
||||
display_str += " IR:";
|
||||
for (auto& point : state.camera_points)
|
||||
{
|
||||
if (point.size == 0xff)
|
||||
display_str += "_,";
|
||||
else
|
||||
display_str += fmt::format("{},{},", point.position.x, point.position.y);
|
||||
}
|
||||
display_str.pop_back();
|
||||
}
|
||||
|
||||
// Nunchuk
|
||||
if (rpt.HasExt() && ext == ExtensionNumber::NUNCHUK)
|
||||
if (state.extension.data.index() != ExtensionNumber::NONE)
|
||||
{
|
||||
const u8* const extData = rpt.GetExtDataPtr();
|
||||
const auto ext_visitor = overloaded{
|
||||
[&](const Nunchuk::DataFormat& nunchuk) {
|
||||
const auto bt = nunchuk.GetButtons();
|
||||
if (bt & Nunchuk::BUTTON_C)
|
||||
display_str += " C";
|
||||
if (bt & Nunchuk::BUTTON_Z)
|
||||
display_str += " Z";
|
||||
display_str += fmt::format(" N-ACC:{},{},{}", nunchuk.GetAccelX(), nunchuk.GetAccelY(),
|
||||
nunchuk.GetAccelZ());
|
||||
display_str += Analog2DToString(nunchuk.jx, nunchuk.jy, " ANA");
|
||||
},
|
||||
[&](const Classic::DataFormat& cc) {
|
||||
const auto bt = cc.GetButtons();
|
||||
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)
|
||||
{
|
||||
if (bt & value)
|
||||
{
|
||||
display_str += ' ';
|
||||
display_str += name;
|
||||
}
|
||||
}
|
||||
constexpr auto trigger_max = (1 << Classic::TRIGGER_BITS) - 1;
|
||||
display_str += Analog1DToString(cc.GetLeftTrigger().value, " L", trigger_max);
|
||||
display_str += Analog1DToString(cc.GetRightTrigger().value, " R", trigger_max);
|
||||
|
||||
Nunchuk::DataFormat nunchuk;
|
||||
memcpy(&nunchuk, extData, sizeof(nunchuk));
|
||||
key.Decrypt((u8*)&nunchuk, 0, sizeof(nunchuk));
|
||||
nunchuk.bt.hex = nunchuk.bt.hex ^ 0x3;
|
||||
constexpr auto lstick_max = (1 << Classic::LEFT_STICK_BITS) - 1;
|
||||
const auto left_stick = cc.GetLeftStick().value;
|
||||
display_str += Analog2DToString(left_stick.x, left_stick.y, " ANA", lstick_max);
|
||||
|
||||
const std::string accel = fmt::format(" N-ACC:{},{},{}", nunchuk.GetAccelX(),
|
||||
nunchuk.GetAccelY(), nunchuk.GetAccelZ());
|
||||
|
||||
if (nunchuk.bt.c)
|
||||
display_str += " C";
|
||||
if (nunchuk.bt.z)
|
||||
display_str += " Z";
|
||||
display_str += accel;
|
||||
display_str += Analog2DToString(nunchuk.jx, nunchuk.jy, " ANA");
|
||||
}
|
||||
|
||||
// Classic controller
|
||||
if (rpt.HasExt() && ext == ExtensionNumber::CLASSIC)
|
||||
{
|
||||
const u8* const extData = rpt.GetExtDataPtr();
|
||||
|
||||
Classic::DataFormat cc;
|
||||
memcpy(&cc, extData, sizeof(cc));
|
||||
key.Decrypt((u8*)&cc, 0, sizeof(cc));
|
||||
cc.bt.hex = cc.bt.hex ^ 0xFFFF;
|
||||
|
||||
if (cc.bt.dpad_left)
|
||||
display_str += " LEFT";
|
||||
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);
|
||||
|
||||
const auto left_stick = cc.GetLeftStick().value;
|
||||
display_str += Analog2DToString(left_stick.x, left_stick.y, " ANA", 63);
|
||||
|
||||
const auto right_stick = cc.GetRightStick().value;
|
||||
display_str += Analog2DToString(right_stick.x, right_stick.y, " R-ANA", 31);
|
||||
constexpr auto rstick_max = (1 << Classic::RIGHT_STICK_BITS) - 1;
|
||||
const auto right_stick = cc.GetRightStick().value;
|
||||
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;
|
||||
@ -857,29 +833,32 @@ void MovieManager::RecordInput(const GCPadStatus* PadStatus, int controllerID)
|
||||
}
|
||||
|
||||
// NOTE: CPU Thread
|
||||
void MovieManager::CheckWiimoteStatus(int wiimote, const DataReportBuilder& rpt,
|
||||
ExtensionNumber ext, const EncryptionKey& key)
|
||||
void MovieManager::CheckWiimoteStatus(int wiimote, const DesiredWiimoteState& desired_state)
|
||||
{
|
||||
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);
|
||||
m_input_display[wiimote + 4] = std::move(display_str);
|
||||
}
|
||||
|
||||
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))
|
||||
return;
|
||||
|
||||
InputUpdate();
|
||||
|
||||
const u8 size = serialized_state.length;
|
||||
m_temp_input.resize(m_current_byte + size + 1);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -955,7 +934,7 @@ bool MovieManager::PlayInput(const std::string& movie_path,
|
||||
m_play_mode = PlayMode::Playing;
|
||||
|
||||
// Wiimotes cause desync issues if they're not reset before launching the game
|
||||
Wiimote::ResetAllWiimotes();
|
||||
::Wiimote::ResetAllWiimotes();
|
||||
|
||||
Core::UpdateWantDeterminism(m_system);
|
||||
|
||||
@ -1275,50 +1254,54 @@ void MovieManager::PlayController(GCPadStatus* PadStatus, int controllerID)
|
||||
}
|
||||
|
||||
// NOTE: CPU Thread
|
||||
bool MovieManager::PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt,
|
||||
ExtensionNumber ext, const EncryptionKey& key)
|
||||
bool MovieManager::PlayWiimote(int wiimote, DesiredWiimoteState* desired_state)
|
||||
{
|
||||
if (!IsPlayingInput() || !IsUsingWiimote(wiimote) || m_temp_input.empty())
|
||||
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());
|
||||
EndPlayInput(!m_read_only);
|
||||
return false;
|
||||
}
|
||||
|
||||
const u8 size = rpt.GetDataSize();
|
||||
const u8 sizeInMovie = m_temp_input[m_current_byte];
|
||||
SerializedWiimoteState serialized;
|
||||
serialized.length = m_temp_input[m_current_byte];
|
||||
|
||||
if (size != sizeInMovie)
|
||||
if (serialized.length > serialized.data.size())
|
||||
{
|
||||
PanicAlertFmtT(
|
||||
"Fatal desync. Aborting playback. (Error in PlayWiimote: {0} != {1}, byte {2}.){3}",
|
||||
sizeInMovie, size, m_current_byte,
|
||||
(m_controllers == ControllerTypeArray{}) ?
|
||||
" Try re-creating the recording with all GameCube controllers "
|
||||
"disabled (in Configure > GameCube > Device Settings)." :
|
||||
"");
|
||||
PanicAlertFmtT("Invalid serialized length:{0} in PlayWiimote. byte:{1}", int(serialized.length),
|
||||
m_current_byte);
|
||||
EndPlayInput(!m_read_only);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_current_byte++;
|
||||
|
||||
if (m_current_byte + size > m_temp_input.size())
|
||||
++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, size,
|
||||
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;
|
||||
}
|
||||
|
||||
memcpy(rpt.GetDataPtr(), &m_temp_input[m_current_byte], size);
|
||||
m_current_byte += size;
|
||||
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{}) ?
|
||||
" Try re-creating the recording with all GameCube controllers "
|
||||
"disabled (in Configure > GameCube > Device Settings)." :
|
||||
"");
|
||||
EndPlayInput(!m_read_only);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_current_input_count++;
|
||||
m_current_byte += serialized.length;
|
||||
++m_current_input_count;
|
||||
|
||||
CheckInputEnd();
|
||||
return true;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/HW/WiimoteEmu/DesiredWiimoteState.h"
|
||||
|
||||
struct BootParameters;
|
||||
|
||||
@ -206,21 +207,19 @@ public:
|
||||
bool BeginRecordingInput(const ControllerTypeArray& controllers,
|
||||
const WiimoteEnabledArray& wiimotes);
|
||||
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);
|
||||
void LoadInput(const std::string& movie_path);
|
||||
void ReadHeader();
|
||||
void PlayController(GCPadStatus* PadStatus, int controllerID);
|
||||
bool PlayWiimote(int wiimote, WiimoteCommon::DataReportBuilder& rpt,
|
||||
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
||||
bool PlayWiimote(int wiimote, WiimoteEmu::DesiredWiimoteState* desired_state);
|
||||
void EndPlayInput(bool cont);
|
||||
void SaveRecording(const std::string& filename);
|
||||
void DoState(PointerWrap& p);
|
||||
void Shutdown();
|
||||
void CheckPadStatus(const GCPadStatus* PadStatus, int controllerID);
|
||||
void CheckWiimoteStatus(int wiimote, const WiimoteCommon::DataReportBuilder& rpt,
|
||||
WiimoteEmu::ExtensionNumber ext, const WiimoteEmu::EncryptionKey& key);
|
||||
void CheckWiimoteStatus(int wiimote, const WiimoteEmu::DesiredWiimoteState& desired_state);
|
||||
|
||||
std::string GetInputDisplay();
|
||||
std::string GetRTCDisplay() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user