mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-10 22:49:00 +01:00
WiimoteEmu: Unbreak wiimote extensions.
This commit is contained in:
parent
ebc2e58fa4
commit
62b66580c3
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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(®_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(®_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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user