Skip to content

Commit

Permalink
WiimoteEmu: Minor IR Camera behavior accuracy fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
jordan-woyak committed Feb 23, 2019
1 parent 3426c98 commit d64f29d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h
Expand Up @@ -38,14 +38,14 @@ enum class OutputReportID : u8
Rumble = 0x10, Rumble = 0x10,
LED = 0x11, LED = 0x11,
ReportMode = 0x12, ReportMode = 0x12,
IRPixelClock = 0x13, IRLogicEnable = 0x13,
SpeakerEnable = 0x14, SpeakerEnable = 0x14,
RequestStatus = 0x15, RequestStatus = 0x15,
WriteData = 0x16, WriteData = 0x16,
ReadData = 0x17, ReadData = 0x17,
SpeakerData = 0x18, SpeakerData = 0x18,
SpeakerMute = 0x19, SpeakerMute = 0x19,
IRLogic = 0x1a, IRLogicEnable2 = 0x1a,
}; };


enum class LED : u8 enum class LED : u8
Expand Down
15 changes: 15 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/Camera.cpp
Expand Up @@ -16,18 +16,25 @@ namespace WiimoteEmu
void CameraLogic::Reset() void CameraLogic::Reset()
{ {
reg_data = {}; reg_data = {};

m_is_enabled = false;
} }


void CameraLogic::DoState(PointerWrap& p) void CameraLogic::DoState(PointerWrap& p)
{ {
p.Do(reg_data); p.Do(reg_data);

// FYI: m_is_enabled is handled elsewhere.
} }


int CameraLogic::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out) int CameraLogic::BusRead(u8 slave_addr, u8 addr, int count, u8* data_out)
{ {
if (I2C_ADDR != slave_addr) if (I2C_ADDR != slave_addr)
return 0; return 0;


if (!m_is_enabled)
return 0;

return RawRead(&reg_data, addr, count, data_out); return RawRead(&reg_data, addr, count, data_out);
} }


Expand All @@ -36,6 +43,9 @@ int CameraLogic::BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in)
if (I2C_ADDR != slave_addr) if (I2C_ADDR != slave_addr)
return 0; return 0;


if (!m_is_enabled)
return 0;

return RawWrite(&reg_data, addr, count, data_in); return RawWrite(&reg_data, addr, count, data_in);
} }


Expand Down Expand Up @@ -201,4 +211,9 @@ void CameraLogic::Update(const ControllerEmu::Cursor::StateData& cursor,
} }
} }


void CameraLogic::SetEnabled(bool is_enabled)
{
m_is_enabled = is_enabled;
}

} // namespace WiimoteEmu } // namespace WiimoteEmu
5 changes: 5 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/Camera.h
Expand Up @@ -68,6 +68,7 @@ class CameraLogic : public I2CSlave
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void Update(const ControllerEmu::Cursor::StateData& cursor, const NormalizedAccelData& accel, void Update(const ControllerEmu::Cursor::StateData& cursor, const NormalizedAccelData& accel,
bool sensor_bar_on_top); bool sensor_bar_on_top);
void SetEnabled(bool is_enabled);


static constexpr u8 I2C_ADDR = 0x58; static constexpr u8 I2C_ADDR = 0x58;


Expand Down Expand Up @@ -100,5 +101,9 @@ class CameraLogic : public I2CSlave
int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override; int BusWrite(u8 slave_addr, u8 addr, int count, const u8* data_in) override;


Register reg_data; Register reg_data;

// When disabled the camera does not respond on the bus.
// Change is triggered by wiimote report 0x13.
bool m_is_enabled;
}; };
} // namespace WiimoteEmu } // namespace WiimoteEmu
30 changes: 17 additions & 13 deletions Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Expand Up @@ -101,8 +101,8 @@ void Wiimote::HIDOutputReport(const void* data, u32 size)
case OutputReportID::ReportMode: case OutputReportID::ReportMode:
InvokeHandler<OutputReportMode>(&Wiimote::HandleReportMode, rpt, rpt_size); InvokeHandler<OutputReportMode>(&Wiimote::HandleReportMode, rpt, rpt_size);
break; break;
case OutputReportID::IRPixelClock: case OutputReportID::IRLogicEnable:
InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleIRPixelClock, rpt, rpt_size); InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleIRLogicEnable, rpt, rpt_size);
break; break;
case OutputReportID::SpeakerEnable: case OutputReportID::SpeakerEnable:
InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleSpeakerEnable, rpt, rpt_size); InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleSpeakerEnable, rpt, rpt_size);
Expand All @@ -122,8 +122,8 @@ void Wiimote::HIDOutputReport(const void* data, u32 size)
case OutputReportID::SpeakerMute: case OutputReportID::SpeakerMute:
InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleSpeakerMute, rpt, rpt_size); InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleSpeakerMute, rpt, rpt_size);
break; break;
case OutputReportID::IRLogic: case OutputReportID::IRLogicEnable2:
InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleIRLogic, rpt, rpt_size); InvokeHandler<OutputReportEnableFeature>(&Wiimote::HandleIRLogicEnable2, rpt, rpt_size);
break; break;
default: default:
PanicAlert("HidOutputReport: Unknown report ID 0x%02x", int(rpt.rpt_id)); PanicAlert("HidOutputReport: Unknown report ID 0x%02x", int(rpt.rpt_id));
Expand Down Expand Up @@ -342,24 +342,26 @@ void Wiimote::HandleReportLeds(const WiimoteCommon::OutputReportLeds& rpt)
SendAck(OutputReportID::LED, ErrorCode::Success); SendAck(OutputReportID::LED, ErrorCode::Success);
} }


void Wiimote::HandleIRPixelClock(const WiimoteCommon::OutputReportEnableFeature& rpt) void Wiimote::HandleIRLogicEnable2(const WiimoteCommon::OutputReportEnableFeature& rpt)
{ {
// INFO_LOG(WIIMOTE, "WM IR Clock: %02x", erpt.enable); // FYI: We ignore this and update camera data regardless.

// FYI: Camera data is currently always updated. Ignoring pixel clock status.


if (rpt.ack) if (rpt.ack)
SendAck(OutputReportID::IRPixelClock, ErrorCode::Success); SendAck(OutputReportID::IRLogicEnable2, ErrorCode::Success);
} }


void Wiimote::HandleIRLogic(const WiimoteCommon::OutputReportEnableFeature& rpt) void Wiimote::HandleIRLogicEnable(const WiimoteCommon::OutputReportEnableFeature& rpt)
{ {
// FYI: Camera data is currently always updated. We just save this for status reports. // Note: Wiibrew currently refers to this report (0x13) as "Enable IR Pixel Clock"
// however my testing shows this affects the relevant status bit and whether or not
// the camera responds on the I2C bus.


m_status.ir = rpt.enable; m_status.ir = rpt.enable;


m_camera_logic.SetEnabled(m_status.ir);

if (rpt.ack) if (rpt.ack)
SendAck(OutputReportID::IRLogic, ErrorCode::Success); SendAck(OutputReportID::IRLogicEnable, ErrorCode::Success);
} }


void Wiimote::HandleSpeakerMute(const WiimoteCommon::OutputReportEnableFeature& rpt) void Wiimote::HandleSpeakerMute(const WiimoteCommon::OutputReportEnableFeature& rpt)
Expand All @@ -372,7 +374,6 @@ void Wiimote::HandleSpeakerMute(const WiimoteCommon::OutputReportEnableFeature&


void Wiimote::HandleSpeakerEnable(const WiimoteCommon::OutputReportEnableFeature& rpt) void Wiimote::HandleSpeakerEnable(const WiimoteCommon::OutputReportEnableFeature& rpt)
{ {
// INFO_LOG(WIIMOTE, "WM Speaker Enable: %02x", erpt.enable);
m_status.speaker = rpt.enable; m_status.speaker = rpt.enable;


if (rpt.ack) if (rpt.ack)
Expand Down Expand Up @@ -567,6 +568,9 @@ void Wiimote::DoState(PointerWrap& p)
m_speaker_logic.DoState(p); m_speaker_logic.DoState(p);
m_camera_logic.DoState(p); m_camera_logic.DoState(p);


if (p.GetMode() == PointerWrap::MODE_READ)
m_camera_logic.SetEnabled(m_status.ir);

p.Do(m_is_motion_plus_attached); p.Do(m_is_motion_plus_attached);
p.Do(m_active_extension); p.Do(m_active_extension);


Expand Down
7 changes: 0 additions & 7 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Expand Up @@ -445,13 +445,6 @@ void Wiimote::SendDataReport()
const auto cursor = m_ir->GetState(true); const auto cursor = m_ir->GetState(true);
m_camera_logic.Update(cursor, norm_accel, m_sensor_bar_on_top); m_camera_logic.Update(cursor, norm_accel, m_sensor_bar_on_top);


if (!m_status.ir)
{
// TODO: What does a real wiimote send in this case? 0xFFs ?
// I'm assuming it still reads from the bus?
DEBUG_LOG(WIIMOTE, "Game is reading IR data without enabling IR logic first.");
}

// The real wiimote reads camera data from the i2c bus starting at offset 0x37: // The real wiimote reads camera data from the i2c bus starting at offset 0x37:
const u8 camera_data_offset = const u8 camera_data_offset =
CameraLogic::REPORT_DATA_OFFSET + rpt_builder.GetIRDataFormatOffset(); CameraLogic::REPORT_DATA_OFFSET + rpt_builder.GetIRDataFormatOffset();
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
Expand Up @@ -156,8 +156,8 @@ class Wiimote : public ControllerEmu::EmulatedController
void HandleRequestStatus(const WiimoteCommon::OutputReportRequestStatus&); void HandleRequestStatus(const WiimoteCommon::OutputReportRequestStatus&);
void HandleReadData(const WiimoteCommon::OutputReportReadData&); void HandleReadData(const WiimoteCommon::OutputReportReadData&);
void HandleWriteData(const WiimoteCommon::OutputReportWriteData&); void HandleWriteData(const WiimoteCommon::OutputReportWriteData&);
void HandleIRPixelClock(const WiimoteCommon::OutputReportEnableFeature&); void HandleIRLogicEnable(const WiimoteCommon::OutputReportEnableFeature&);
void HandleIRLogic(const WiimoteCommon::OutputReportEnableFeature&); void HandleIRLogicEnable2(const WiimoteCommon::OutputReportEnableFeature&);
void HandleSpeakerMute(const WiimoteCommon::OutputReportEnableFeature&); void HandleSpeakerMute(const WiimoteCommon::OutputReportEnableFeature&);
void HandleSpeakerEnable(const WiimoteCommon::OutputReportEnableFeature&); void HandleSpeakerEnable(const WiimoteCommon::OutputReportEnableFeature&);
void HandleSpeakerData(const WiimoteCommon::OutputReportSpeakerData&); void HandleSpeakerData(const WiimoteCommon::OutputReportSpeakerData&);
Expand Down

0 comments on commit d64f29d

Please sign in to comment.