WiimoteEmu: Unbreak wiimote extensions.

This commit is contained in:
Jordan Woyak 2018-11-22 19:12:42 -06:00
parent ebc2e58fa4
commit 62b66580c3
3 changed files with 69 additions and 71 deletions

View File

@ -266,15 +266,7 @@ void Wiimote::WriteData(const wm_write_data* const wd)
return;
// TODO: extension register stuff..
//if (false)//&m_reg_ext == region_ptr)
//{
// // Run the key generation on all writes in the key area, it doesn't matter
// // that we send it parts of a key, only the last full key will have an effect
// if (address >= 0xa40040 && address <= 0xa4004c)
// WiimoteGenerateKey(&m_ext_key, m_reg_ext.encryption_key);
//}
//else if (&m_reg_motion_plus == region_ptr)
//{
// // activate/deactivate motion plus
@ -345,25 +337,8 @@ void Wiimote::ReadData(const wm_read_data* const rd)
{
// Read from Control Register
// ignore second byte for extension area
if (0xA4 == (address >> 16))
address &= 0xFF00FF;
const u8 region_offset = (u8)address;
void* region_ptr = nullptr;
//int region_size = 0;
m_i2c_bus.BusRead(address >> 17, address & 0xff, rd->size, block);
// TODO: generate read errors
if (&m_reg_ext == region_ptr)
{
// Encrypt data read from extension register
// Check if encrypted reads is on
if (0xaa == m_reg_ext.encryption)
WiimoteEncrypt(&m_ext_key, block, address & 0xffff, (u8)size);
}
}
break;
@ -458,11 +433,11 @@ void Wiimote::DoState(PointerWrap& p)
p.Do(m_sensor_bar_on_top);
p.Do(m_status);
p.Do(m_adpcm_state);
p.Do(m_ext_key);
p.Do(m_ext_logic.ext_key);
p.DoArray(m_eeprom);
p.Do(m_reg_motion_plus);
p.Do(m_camera_logic.reg_data);
p.Do(m_reg_ext);
p.Do(m_ext_logic.reg_data);
p.Do(m_reg_speaker);
// Do 'm_read_requests' queue

View File

@ -329,9 +329,11 @@ void Wiimote::Reset()
// set up the register
memset(&m_reg_speaker, 0, sizeof(m_reg_speaker));
// TODO: kill/move this
// TODO: kill/move these
memset(&m_camera_logic.reg_data, 0, sizeof(m_camera_logic.reg_data));
memset(&m_reg_ext, 0, sizeof(m_reg_ext));
memset(&m_ext_logic.reg_data, 0, sizeof(m_ext_logic.reg_data));
memset(&m_reg_motion_plus, 0, sizeof(m_reg_motion_plus));
memcpy(&m_reg_motion_plus.ext_identifier, motion_plus_id, sizeof(motion_plus_id));
@ -363,7 +365,10 @@ void Wiimote::Reset()
m_adpcm_state.step = 127;
// Initialize i2c bus
// TODO: kill magic numbers
m_i2c_bus.Reset();
m_i2c_bus.AddSlave(0x58, &m_camera_logic);
m_i2c_bus.AddSlave(0x52, &m_ext_logic);
}
Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1)
@ -421,12 +426,12 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1
// extension
groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension")));
m_extension->attachments.emplace_back(new WiimoteEmu::None(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::Nunchuk(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::Classic(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::Guitar(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::Drums(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::Turntable(m_reg_ext));
m_extension->attachments.emplace_back(new WiimoteEmu::None(m_ext_logic.reg_data));
m_extension->attachments.emplace_back(new WiimoteEmu::Nunchuk(m_ext_logic.reg_data));
m_extension->attachments.emplace_back(new WiimoteEmu::Classic(m_ext_logic.reg_data));
m_extension->attachments.emplace_back(new WiimoteEmu::Guitar(m_ext_logic.reg_data));
m_extension->attachments.emplace_back(new WiimoteEmu::Drums(m_ext_logic.reg_data));
m_extension->attachments.emplace_back(new WiimoteEmu::Turntable(m_ext_logic.reg_data));
// rumble
groups.emplace_back(m_rumble = new ControllerEmu::ControlGroup(_trans("Rumble")));
@ -835,17 +840,10 @@ void Wiimote::UpdateIRData(bool use_accel)
}
}
void Wiimote::GetExtData(u8* const data)
void Wiimote::UpdateExtData()
{
m_extension->GetState(data);
// i dont think anything accesses the extension data like this, but ill support it. Indeed,
// commercial games don't do this.
// i think it should be unencrpyted in the register, encrypted when read.
memcpy(m_reg_ext.controller_data, data, sizeof(wm_nc)); // TODO: Should it be nc specific?
if (0xAA == m_reg_ext.encryption)
WiimoteEncrypt(&m_ext_key, data, 0x00, sizeof(wm_nc));
// Write extension data to addr 0x00 of extension register
m_extension->GetState(m_ext_logic.reg_data.controller_data);
}
void Wiimote::Update()
@ -871,7 +869,7 @@ void Wiimote::Update()
const ReportFeatures& rptf = reporting_mode_features[m_reporting_mode - RT_REPORT_CORE];
s8 rptf_size = rptf.size;
if (Movie::IsPlayingInput() &&
Movie::PlayWiimote(m_index, data, rptf, m_extension->active_extension, m_ext_key))
Movie::PlayWiimote(m_index, data, rptf, m_extension->active_extension, m_ext_logic.ext_key))
{
if (rptf.core)
m_status.buttons = *reinterpret_cast<wm_buttons*>(data + rptf.core);
@ -910,18 +908,21 @@ void Wiimote::Update()
UpdateIRData(rptf.accel != 0);
if (rptf.ir)
{
// TODO: kill magic numbers
m_i2c_bus.BusRead(0x58, 0x37, rptf.ir, feature_ptr);
feature_ptr += rptf.ir;
}
// extension
UpdateExtData();
if (rptf.ext)
{
// GetExtData(feature_ptr, rptf.ext);
// TODO: kill magic numbers
m_i2c_bus.BusRead(0x52, 0x00, rptf.ext, feature_ptr);
feature_ptr += rptf.ext;
}
Movie::CallWiiInputManip(data, rptf, m_index, m_extension->active_extension, m_ext_key);
Movie::CallWiiInputManip(data, rptf, m_index, m_extension->active_extension, m_ext_logic.ext_key);
}
if (NetPlay::IsNetPlayRunning())
{
@ -930,7 +931,8 @@ void Wiimote::Update()
m_status.buttons = *reinterpret_cast<wm_buttons*>(data + rptf.core);
}
Movie::CheckWiimoteStatus(m_index, data, rptf, m_extension->active_extension, m_ext_key);
// TODO: need to fix usage of rptf probably
Movie::CheckWiimoteStatus(m_index, data, rptf, m_extension->active_extension, m_ext_logic.ext_key);
// don't send a data report if auto reporting is off
if (false == m_reporting_auto && data[1] >= RT_REPORT_CORE)

View File

@ -8,11 +8,11 @@
#include <queue>
#include <string>
#include "Common/Logging/Log.h"
#include "Core/HW/WiimoteCommon/WiimoteHid.h"
#include "Core/HW/WiimoteCommon/WiimoteReport.h"
#include "Core/HW/WiimoteEmu/Encryption.h"
#include "InputCommon/ControllerEmu/ControllerEmu.h"
#include "Common/Logging/Log.h"
// Registry sizes
#define WIIMOTE_EEPROM_SIZE (16 * 1024)
@ -159,11 +159,10 @@ struct ADPCMState
struct ExtensionReg
{
u8 unknown1[0x08];
// 16 bytes of possible extension data
u8 controller_data[0x10];
// address 0x08
u8 controller_data[0x06];
u8 unknown2[0x12];
u8 unknown2[0x10];
// address 0x20
u8 calibration[0x10];
@ -182,6 +181,8 @@ struct ExtensionReg
};
#pragma pack(pop)
static_assert(0x100 == sizeof(ExtensionReg));
void UpdateCalibrationDataChecksum(std::array<u8, 0x10>& data);
void EmulateShake(AccelData* accel, ControllerEmu::Buttons* buttons_group, double intensity,
@ -244,20 +245,11 @@ public:
class I2CBus
{
public:
void AddSlave(u8 addr, I2CSlave* slave)
{
m_slaves.insert(std::make_pair(addr, slave));
}
void AddSlave(u8 addr, I2CSlave* slave) { m_slaves.insert(std::make_pair(addr, slave)); }
void RemoveSlave(u8 addr)
{
m_slaves.erase(addr);
}
void RemoveSlave(u8 addr) { m_slaves.erase(addr); }
void Reset()
{
m_slaves.clear();
}
void Reset() { m_slaves.clear(); }
int BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
{
@ -338,7 +330,7 @@ protected:
void GetButtonData(u8* data);
void GetAccelData(u8* data);
void UpdateIRData(bool use_accel);
void GetExtData(u8* data);
void UpdateExtData();
bool HaveExtension() const;
bool WantExtension() const;
@ -371,6 +363,39 @@ private:
} m_camera_logic;
struct ExtensionLogic : public I2CSlave
{
ExtensionReg reg_data;
wiimote_key ext_key;
int BusRead(u8 addr, int count, u8* data_out) override
{
auto const result = raw_read(&reg_data, addr, count, data_out);
// Encrypt data read from extension register
// Check if encrypted reads is on
if (0xaa == reg_data.encryption)
WiimoteEncrypt(&ext_key, data_out, addr, (u8)count);
return result;
}
int BusWrite(u8 addr, int count, const u8* data_in) override
{
auto const result = raw_write(&reg_data, addr, count, data_in);
if (addr + count > 0x40 && addr < 0x50)
{
// Run the key generation on all writes in the key area, it doesn't matter
// that we send it parts of a key, only the last full key will have an effect
WiimoteGenerateKey(&ext_key, reg_data.encryption_key);
}
return result;
}
} m_ext_logic;
struct ReadRequest
{
// u16 channel;
@ -445,8 +470,6 @@ private:
// maybe read requests cancel any current requests
std::queue<ReadRequest> m_read_requests;
wiimote_key m_ext_key;
#pragma pack(push, 1)
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
struct MotionPlusReg
@ -462,8 +485,6 @@ private:
u8 ext_identifier[6];
} m_reg_motion_plus;
ExtensionReg m_reg_ext;
struct SpeakerReg
{
u8 unused_0;