Merge pull request #8054 from jordan-woyak/emu-wm-determinism-check
WiimoteEmu: Report game quirk on direct read of EXT/IR input.
This commit is contained in:
commit
6cc1e7cfdb
|
@ -139,7 +139,8 @@ void DolphinAnalytics::ReportGameStart()
|
||||||
|
|
||||||
// Keep in sync with enum class GameQuirk definition.
|
// Keep in sync with enum class GameQuirk definition.
|
||||||
static const char* GAME_QUIRKS_NAMES[] = {
|
static const char* GAME_QUIRKS_NAMES[] = {
|
||||||
"icache-matters", // ICACHE_MATTERS
|
"icache-matters",
|
||||||
|
"directly-reads-wiimote-input",
|
||||||
};
|
};
|
||||||
static_assert(sizeof(GAME_QUIRKS_NAMES) / sizeof(GAME_QUIRKS_NAMES[0]) ==
|
static_assert(sizeof(GAME_QUIRKS_NAMES) / sizeof(GAME_QUIRKS_NAMES[0]) ==
|
||||||
static_cast<u32>(GameQuirk::COUNT),
|
static_cast<u32>(GameQuirk::COUNT),
|
||||||
|
|
|
@ -24,6 +24,10 @@ enum class GameQuirk
|
||||||
// Sometimes code run from ICache is different from its mirror in RAM.
|
// Sometimes code run from ICache is different from its mirror in RAM.
|
||||||
ICACHE_MATTERS = 0,
|
ICACHE_MATTERS = 0,
|
||||||
|
|
||||||
|
// The Wii remote hardware makes it possible to bypass normal data reporting and directly
|
||||||
|
// "read" extension or IR data. This would break our current TAS/NetPlay implementation.
|
||||||
|
DIRECTLY_READS_WIIMOTE_INPUT,
|
||||||
|
|
||||||
COUNT,
|
COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ public:
|
||||||
void SetEnabled(bool is_enabled);
|
void SetEnabled(bool is_enabled);
|
||||||
|
|
||||||
static constexpr u8 I2C_ADDR = 0x58;
|
static constexpr u8 I2C_ADDR = 0x58;
|
||||||
|
static constexpr int CAMERA_DATA_BYTES = 36;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO: some of this memory is write-only and should return error 7.
|
// TODO: some of this memory is write-only and should return error 7.
|
||||||
|
@ -89,7 +90,7 @@ private:
|
||||||
u8 mode;
|
u8 mode;
|
||||||
u8 unk[3];
|
u8 unk[3];
|
||||||
// addr: 0x37
|
// addr: 0x37
|
||||||
u8 camera_data[36];
|
u8 camera_data[CAMERA_DATA_BYTES];
|
||||||
u8 unk2[165];
|
u8 unk2[165];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/Swap.h"
|
#include "Common/Swap.h"
|
||||||
|
#include "Core/Analytics.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
|
||||||
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
|
||||||
|
@ -507,6 +508,19 @@ bool Wiimote::ProcessReadDataRequest()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It is possible to bypass data reporting and directly read extension input.
|
||||||
|
// While I am not aware of any games that actually do this,
|
||||||
|
// our NetPlay and TAS methods are completely unprepared for it.
|
||||||
|
const bool is_reading_ext = EncryptedExtension::I2C_ADDR == m_read_request.slave_address &&
|
||||||
|
m_read_request.address < EncryptedExtension::CONTROLLER_DATA_BYTES;
|
||||||
|
const bool is_reading_ir =
|
||||||
|
CameraLogic::I2C_ADDR == m_read_request.slave_address &&
|
||||||
|
m_read_request.address < CameraLogic::REPORT_DATA_OFFSET + CameraLogic::CAMERA_DATA_BYTES &&
|
||||||
|
m_read_request.address + m_read_request.size > CameraLogic::REPORT_DATA_OFFSET;
|
||||||
|
|
||||||
|
if (is_reading_ext || is_reading_ir)
|
||||||
|
DolphinAnalytics::Instance()->ReportGameQuirk(GameQuirk::DIRECTLY_READS_WIIMOTE_INPUT);
|
||||||
|
|
||||||
// Top byte of address is ignored on the bus, but it IS maintained in the read-reply.
|
// Top byte of address is ignored on the bus, but it IS maintained in the read-reply.
|
||||||
auto const bytes_read = m_i2c_bus.BusRead(
|
auto const bytes_read = m_i2c_bus.BusRead(
|
||||||
m_read_request.slave_address, (u8)m_read_request.address, bytes_to_read, reply.data);
|
m_read_request.slave_address, (u8)m_read_request.address, bytes_to_read, reply.data);
|
||||||
|
|
|
@ -62,6 +62,7 @@ class EncryptedExtension : public Extension
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr u8 I2C_ADDR = 0x52;
|
static constexpr u8 I2C_ADDR = 0x52;
|
||||||
|
static constexpr int CONTROLLER_DATA_BYTES = 21;
|
||||||
|
|
||||||
using Extension::Extension;
|
using Extension::Extension;
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ protected:
|
||||||
struct Register
|
struct Register
|
||||||
{
|
{
|
||||||
// 21 bytes of possible extension data
|
// 21 bytes of possible extension data
|
||||||
u8 controller_data[21];
|
u8 controller_data[CONTROLLER_DATA_BYTES];
|
||||||
|
|
||||||
u8 unknown2[11];
|
u8 unknown2[11];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue