summaryrefslogtreecommitdiff
path: root/src/input_common/helpers/joycon_protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common/helpers/joycon_protocol')
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.cpp13
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.h7
-rw-r--r--src/input_common/helpers/joycon_protocol/irs.cpp300
-rw-r--r--src/input_common/helpers/joycon_protocol/irs.h63
-rw-r--r--src/input_common/helpers/joycon_protocol/joycon_types.h107
-rw-r--r--src/input_common/helpers/joycon_protocol/poller.cpp6
-rw-r--r--src/input_common/helpers/joycon_protocol/poller.h3
7 files changed, 496 insertions, 3 deletions
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
index a4d08fdaf..a329db107 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
@@ -120,6 +120,19 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const
120 return DriverResult::Success; 120 return DriverResult::Success;
121} 121}
122 122
123DriverResult JoyconCommonProtocol::SendMcuCommand(SubCommand sc, std::span<const u8> buffer) {
124 std::vector<u8> local_buffer(MaxResponseSize);
125
126 local_buffer[0] = static_cast<u8>(OutputReport::MCU_DATA);
127 local_buffer[1] = GetCounter();
128 local_buffer[10] = static_cast<u8>(sc);
129 for (std::size_t i = 0; i < buffer.size(); ++i) {
130 local_buffer[11 + i] = buffer[i];
131 }
132
133 return SendData(local_buffer);
134}
135
123DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffer) { 136DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffer) {
124 std::vector<u8> local_buffer(MaxResponseSize); 137 std::vector<u8> local_buffer(MaxResponseSize);
125 138
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.h b/src/input_common/helpers/joycon_protocol/common_protocol.h
index a65e4aa76..2a3feaf59 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.h
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.h
@@ -75,6 +75,13 @@ public:
75 DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output); 75 DriverResult SendSubCommand(SubCommand sc, std::span<const u8> buffer, std::vector<u8>& output);
76 76
77 /** 77 /**
78 * Sends a mcu command to the device
79 * @param sc sub command to be send
80 * @param buffer data to be send
81 */
82 DriverResult SendMcuCommand(SubCommand sc, std::span<const u8> buffer);
83
84 /**
78 * Sends vibration data to the joycon 85 * Sends vibration data to the joycon
79 * @param buffer data to be send 86 * @param buffer data to be send
80 */ 87 */
diff --git a/src/input_common/helpers/joycon_protocol/irs.cpp b/src/input_common/helpers/joycon_protocol/irs.cpp
new file mode 100644
index 000000000..9dfa503c2
--- /dev/null
+++ b/src/input_common/helpers/joycon_protocol/irs.cpp
@@ -0,0 +1,300 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <thread>
5#include "common/logging/log.h"
6#include "input_common/helpers/joycon_protocol/irs.h"
7
8namespace InputCommon::Joycon {
9
10IrsProtocol::IrsProtocol(std::shared_ptr<JoyconHandle> handle)
11 : JoyconCommonProtocol(std::move(handle)) {}
12
13DriverResult IrsProtocol::EnableIrs() {
14 LOG_INFO(Input, "Enable IRS");
15 DriverResult result{DriverResult::Success};
16 SetBlocking();
17
18 if (result == DriverResult::Success) {
19 result = SetReportMode(ReportMode::NFC_IR_MODE_60HZ);
20 }
21 if (result == DriverResult::Success) {
22 result = EnableMCU(true);
23 }
24 if (result == DriverResult::Success) {
25 result = WaitSetMCUMode(ReportMode::NFC_IR_MODE_60HZ, MCUMode::Standby);
26 }
27 if (result == DriverResult::Success) {
28 const MCUConfig config{
29 .command = MCUCommand::ConfigureMCU,
30 .sub_command = MCUSubCommand::SetMCUMode,
31 .mode = MCUMode::IR,
32 .crc = {},
33 };
34
35 result = ConfigureMCU(config);
36 }
37 if (result == DriverResult::Success) {
38 result = WaitSetMCUMode(ReportMode::NFC_IR_MODE_60HZ, MCUMode::IR);
39 }
40 if (result == DriverResult::Success) {
41 result = ConfigureIrs();
42 }
43 if (result == DriverResult::Success) {
44 result = WriteRegistersStep1();
45 }
46 if (result == DriverResult::Success) {
47 result = WriteRegistersStep2();
48 }
49
50 is_enabled = true;
51
52 SetNonBlocking();
53 return result;
54}
55
56DriverResult IrsProtocol::DisableIrs() {
57 LOG_DEBUG(Input, "Disable IRS");
58 DriverResult result{DriverResult::Success};
59 SetBlocking();
60
61 if (result == DriverResult::Success) {
62 result = EnableMCU(false);
63 }
64
65 is_enabled = false;
66
67 SetNonBlocking();
68 return result;
69}
70
71DriverResult IrsProtocol::SetIrsConfig(IrsMode mode, IrsResolution format) {
72 irs_mode = mode;
73 switch (format) {
74 case IrsResolution::Size320x240:
75 resolution_code = IrsResolutionCode::Size320x240;
76 fragments = IrsFragments::Size320x240;
77 resolution = IrsResolution::Size320x240;
78 break;
79 case IrsResolution::Size160x120:
80 resolution_code = IrsResolutionCode::Size160x120;
81 fragments = IrsFragments::Size160x120;
82 resolution = IrsResolution::Size160x120;
83 break;
84 case IrsResolution::Size80x60:
85 resolution_code = IrsResolutionCode::Size80x60;
86 fragments = IrsFragments::Size80x60;
87 resolution = IrsResolution::Size80x60;
88 break;
89 case IrsResolution::Size20x15:
90 resolution_code = IrsResolutionCode::Size20x15;
91 fragments = IrsFragments::Size20x15;
92 resolution = IrsResolution::Size20x15;
93 break;
94 case IrsResolution::Size40x30:
95 default:
96 resolution_code = IrsResolutionCode::Size40x30;
97 fragments = IrsFragments::Size40x30;
98 resolution = IrsResolution::Size40x30;
99 break;
100 }
101
102 // Restart feature
103 if (is_enabled) {
104 DisableIrs();
105 return EnableIrs();
106 }
107
108 return DriverResult::Success;
109}
110
111DriverResult IrsProtocol::RequestImage(std::span<u8> buffer) {
112 const u8 next_packet_fragment =
113 static_cast<u8>((packet_fragment + 1) % (static_cast<u8>(fragments) + 1));
114
115 if (buffer[0] == 0x31 && buffer[49] == 0x03) {
116 u8 new_packet_fragment = buffer[52];
117 if (new_packet_fragment == next_packet_fragment) {
118 packet_fragment = next_packet_fragment;
119 memcpy(buf_image.data() + (300 * packet_fragment), buffer.data() + 59, 300);
120
121 return RequestFrame(packet_fragment);
122 }
123
124 if (new_packet_fragment == packet_fragment) {
125 return RequestFrame(packet_fragment);
126 }
127
128 return ResendFrame(next_packet_fragment);
129 }
130
131 return RequestFrame(packet_fragment);
132}
133
134DriverResult IrsProtocol::ConfigureIrs() {
135 LOG_DEBUG(Input, "Configure IRS");
136 constexpr std::size_t max_tries = 28;
137 std::vector<u8> output;
138 std::size_t tries = 0;
139
140 const IrsConfigure irs_configuration{
141 .command = MCUCommand::ConfigureIR,
142 .sub_command = MCUSubCommand::SetDeviceMode,
143 .irs_mode = IrsMode::ImageTransfer,
144 .number_of_fragments = fragments,
145 .mcu_major_version = 0x0500,
146 .mcu_minor_version = 0x1800,
147 .crc = {},
148 };
149 buf_image.resize((static_cast<u8>(fragments) + 1) * 300);
150
151 std::vector<u8> request_data(sizeof(IrsConfigure));
152 memcpy(request_data.data(), &irs_configuration, sizeof(IrsConfigure));
153 request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
154 do {
155 const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, request_data, output);
156
157 if (result != DriverResult::Success) {
158 return result;
159 }
160 if (tries++ >= max_tries) {
161 return DriverResult::WrongReply;
162 }
163 } while (output[15] != 0x0b);
164
165 return DriverResult::Success;
166}
167
168DriverResult IrsProtocol::WriteRegistersStep1() {
169 LOG_DEBUG(Input, "WriteRegistersStep1");
170 DriverResult result{DriverResult::Success};
171 constexpr std::size_t max_tries = 28;
172 std::vector<u8> output;
173 std::size_t tries = 0;
174
175 const IrsWriteRegisters irs_registers{
176 .command = MCUCommand::ConfigureIR,
177 .sub_command = MCUSubCommand::WriteDeviceRegisters,
178 .number_of_registers = 0x9,
179 .registers =
180 {
181 IrsRegister{IrRegistersAddress::Resolution, static_cast<u8>(resolution_code)},
182 {IrRegistersAddress::ExposureLSB, static_cast<u8>(exposure & 0xff)},
183 {IrRegistersAddress::ExposureMSB, static_cast<u8>(exposure >> 8)},
184 {IrRegistersAddress::ExposureTime, 0x00},
185 {IrRegistersAddress::Leds, static_cast<u8>(leds)},
186 {IrRegistersAddress::DigitalGainLSB, static_cast<u8>((digital_gain & 0x0f) << 4)},
187 {IrRegistersAddress::DigitalGainMSB, static_cast<u8>((digital_gain & 0xf0) >> 4)},
188 {IrRegistersAddress::LedFilter, static_cast<u8>(led_filter)},
189 {IrRegistersAddress::WhitePixelThreshold, 0xc8},
190 },
191 .crc = {},
192 };
193
194 std::vector<u8> request_data(sizeof(IrsWriteRegisters));
195 memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters));
196 request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
197
198 std::array<u8, 38> mcu_request{0x02};
199 mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36);
200 mcu_request[37] = 0xFF;
201
202 if (result != DriverResult::Success) {
203 return result;
204 }
205
206 do {
207 result = SendSubCommand(SubCommand::SET_MCU_CONFIG, request_data, output);
208
209 // First time we need to set the report mode
210 if (result == DriverResult::Success && tries == 0) {
211 result = SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
212 }
213 if (result == DriverResult::Success && tries == 0) {
214 GetSubCommandResponse(SubCommand::SET_MCU_CONFIG, output);
215 }
216
217 if (result != DriverResult::Success) {
218 return result;
219 }
220 if (tries++ >= max_tries) {
221 return DriverResult::WrongReply;
222 }
223 } while (!(output[15] == 0x13 && output[17] == 0x07) && output[15] != 0x23);
224
225 return DriverResult::Success;
226}
227
228DriverResult IrsProtocol::WriteRegistersStep2() {
229 LOG_DEBUG(Input, "WriteRegistersStep2");
230 constexpr std::size_t max_tries = 28;
231 std::vector<u8> output;
232 std::size_t tries = 0;
233
234 const IrsWriteRegisters irs_registers{
235 .command = MCUCommand::ConfigureIR,
236 .sub_command = MCUSubCommand::WriteDeviceRegisters,
237 .number_of_registers = 0x8,
238 .registers =
239 {
240 IrsRegister{IrRegistersAddress::LedIntensitiyMSB,
241 static_cast<u8>(led_intensity >> 8)},
242 {IrRegistersAddress::LedIntensitiyLSB, static_cast<u8>(led_intensity & 0xff)},
243 {IrRegistersAddress::ImageFlip, static_cast<u8>(image_flip)},
244 {IrRegistersAddress::DenoiseSmoothing, static_cast<u8>((denoise >> 16) & 0xff)},
245 {IrRegistersAddress::DenoiseEdge, static_cast<u8>((denoise >> 8) & 0xff)},
246 {IrRegistersAddress::DenoiseColor, static_cast<u8>(denoise & 0xff)},
247 {IrRegistersAddress::UpdateTime, 0x2d},
248 {IrRegistersAddress::FinalizeConfig, 0x01},
249 },
250 .crc = {},
251 };
252
253 std::vector<u8> request_data(sizeof(IrsWriteRegisters));
254 memcpy(request_data.data(), &irs_registers, sizeof(IrsWriteRegisters));
255 request_data[37] = CalculateMCU_CRC8(request_data.data() + 1, 36);
256 do {
257 const auto result = SendSubCommand(SubCommand::SET_MCU_CONFIG, request_data, output);
258
259 if (result != DriverResult::Success) {
260 return result;
261 }
262 if (tries++ >= max_tries) {
263 return DriverResult::WrongReply;
264 }
265 } while (output[15] != 0x13 && output[15] != 0x23);
266
267 return DriverResult::Success;
268}
269
270DriverResult IrsProtocol::RequestFrame(u8 frame) {
271 std::array<u8, 38> mcu_request{};
272 mcu_request[3] = frame;
273 mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36);
274 mcu_request[37] = 0xFF;
275 return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
276}
277
278DriverResult IrsProtocol::ResendFrame(u8 frame) {
279 std::array<u8, 38> mcu_request{};
280 mcu_request[1] = 0x1;
281 mcu_request[2] = frame;
282 mcu_request[3] = 0x0;
283 mcu_request[36] = CalculateMCU_CRC8(mcu_request.data(), 36);
284 mcu_request[37] = 0xFF;
285 return SendMcuCommand(SubCommand::SET_REPORT_MODE, mcu_request);
286}
287
288std::vector<u8> IrsProtocol::GetImage() const {
289 return buf_image;
290}
291
292IrsResolution IrsProtocol::GetIrsFormat() const {
293 return resolution;
294}
295
296bool IrsProtocol::IsEnabled() const {
297 return is_enabled;
298}
299
300} // namespace InputCommon::Joycon
diff --git a/src/input_common/helpers/joycon_protocol/irs.h b/src/input_common/helpers/joycon_protocol/irs.h
new file mode 100644
index 000000000..76dfa02ea
--- /dev/null
+++ b/src/input_common/helpers/joycon_protocol/irs.h
@@ -0,0 +1,63 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// Based on dkms-hid-nintendo implementation, CTCaer joycon toolkit and dekuNukem reverse
5// engineering https://github.com/nicman23/dkms-hid-nintendo/blob/master/src/hid-nintendo.c
6// https://github.com/CTCaer/jc_toolkit
7// https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering
8
9#pragma once
10
11#include <vector>
12
13#include "input_common/helpers/joycon_protocol/common_protocol.h"
14#include "input_common/helpers/joycon_protocol/joycon_types.h"
15
16namespace InputCommon::Joycon {
17
18class IrsProtocol final : private JoyconCommonProtocol {
19public:
20 explicit IrsProtocol(std::shared_ptr<JoyconHandle> handle);
21
22 DriverResult EnableIrs();
23
24 DriverResult DisableIrs();
25
26 DriverResult SetIrsConfig(IrsMode mode, IrsResolution format);
27
28 DriverResult RequestImage(std::span<u8> buffer);
29
30 std::vector<u8> GetImage() const;
31
32 IrsResolution GetIrsFormat() const;
33
34 bool IsEnabled() const;
35
36private:
37 DriverResult ConfigureIrs();
38
39 DriverResult WriteRegistersStep1();
40 DriverResult WriteRegistersStep2();
41
42 DriverResult RequestFrame(u8 frame);
43 DriverResult ResendFrame(u8 frame);
44
45 IrsMode irs_mode{IrsMode::ImageTransfer};
46 IrsResolution resolution{IrsResolution::Size40x30};
47 IrsResolutionCode resolution_code{IrsResolutionCode::Size40x30};
48 IrsFragments fragments{IrsFragments::Size40x30};
49 IrLeds leds{IrLeds::BrightAndDim};
50 IrExLedFilter led_filter{IrExLedFilter::Enabled};
51 IrImageFlip image_flip{IrImageFlip::Normal};
52 u8 digital_gain{0x01};
53 u16 exposure{0x2490};
54 u16 led_intensity{0x0f10};
55 u32 denoise{0x012344};
56
57 u8 packet_fragment{};
58 std::vector<u8> buf_image; // 8bpp greyscale image.
59
60 bool is_enabled{};
61};
62
63} // namespace InputCommon::Joycon
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index 36c00a8d7..273c8d07d 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -18,7 +18,7 @@
18 18
19namespace InputCommon::Joycon { 19namespace InputCommon::Joycon {
20constexpr u32 MaxErrorCount = 50; 20constexpr u32 MaxErrorCount = 50;
21constexpr u32 MaxBufferSize = 60; 21constexpr u32 MaxBufferSize = 368;
22constexpr u32 MaxResponseSize = 49; 22constexpr u32 MaxResponseSize = 49;
23constexpr u32 MaxSubCommandResponseSize = 64; 23constexpr u32 MaxSubCommandResponseSize = 64;
24constexpr std::array<u8, 8> DefaultVibrationBuffer{0x0, 0x1, 0x40, 0x40, 0x0, 0x1, 0x40, 0x40}; 24constexpr std::array<u8, 8> DefaultVibrationBuffer{0x0, 0x1, 0x40, 0x40, 0x0, 0x1, 0x40, 0x40};
@@ -273,6 +273,80 @@ enum class NFCTagType : u8 {
273 Ntag215 = 0x01, 273 Ntag215 = 0x01,
274}; 274};
275 275
276enum class IrsMode : u8 {
277 None = 0x02,
278 Moment = 0x03,
279 Dpd = 0x04,
280 Clustering = 0x06,
281 ImageTransfer = 0x07,
282 Silhouette = 0x08,
283 TeraImage = 0x09,
284 SilhouetteTeraImage = 0x0A,
285};
286
287enum class IrsResolution {
288 Size320x240,
289 Size160x120,
290 Size80x60,
291 Size40x30,
292 Size20x15,
293 None,
294};
295
296enum class IrsResolutionCode : u8 {
297 Size320x240 = 0x00, // Full pixel array
298 Size160x120 = 0x50, // Sensor Binning [2 X 2]
299 Size80x60 = 0x64, // Sensor Binning [4 x 2] and Skipping [1 x 2]
300 Size40x30 = 0x69, // Sensor Binning [4 x 2] and Skipping [2 x 4]
301 Size20x15 = 0x6A, // Sensor Binning [4 x 2] and Skipping [4 x 4]
302};
303
304// Size of image divided by 300
305enum class IrsFragments : u8 {
306 Size20x15 = 0x00,
307 Size40x30 = 0x03,
308 Size80x60 = 0x0f,
309 Size160x120 = 0x3f,
310 Size320x240 = 0xFF,
311};
312
313enum class IrLeds : u8 {
314 BrightAndDim = 0x00,
315 Bright = 0x20,
316 Dim = 0x10,
317 None = 0x30,
318};
319
320enum class IrExLedFilter : u8 {
321 Disabled = 0x00,
322 Enabled = 0x03,
323};
324
325enum class IrImageFlip : u8 {
326 Normal = 0x00,
327 Inverted = 0x02,
328};
329
330enum class IrRegistersAddress : u16 {
331 UpdateTime = 0x0400,
332 FinalizeConfig = 0x0700,
333 LedFilter = 0x0e00,
334 Leds = 0x1000,
335 LedIntensitiyMSB = 0x1100,
336 LedIntensitiyLSB = 0x1200,
337 ImageFlip = 0x2d00,
338 Resolution = 0x2e00,
339 DigitalGainLSB = 0x2e01,
340 DigitalGainMSB = 0x2f01,
341 ExposureLSB = 0x3001,
342 ExposureMSB = 0x3101,
343 ExposureTime = 0x3201,
344 WhitePixelThreshold = 0x4301,
345 DenoiseSmoothing = 0x6701,
346 DenoiseEdge = 0x6801,
347 DenoiseColor = 0x6901,
348};
349
276enum class DriverResult { 350enum class DriverResult {
277 Success, 351 Success,
278 WrongReply, 352 WrongReply,
@@ -456,6 +530,36 @@ struct NFCRequestState {
456}; 530};
457static_assert(sizeof(NFCRequestState) == 0x26, "NFCRequestState is an invalid size"); 531static_assert(sizeof(NFCRequestState) == 0x26, "NFCRequestState is an invalid size");
458 532
533struct IrsConfigure {
534 MCUCommand command;
535 MCUSubCommand sub_command;
536 IrsMode irs_mode;
537 IrsFragments number_of_fragments;
538 u16 mcu_major_version;
539 u16 mcu_minor_version;
540 INSERT_PADDING_BYTES(0x1D);
541 u8 crc;
542};
543static_assert(sizeof(IrsConfigure) == 0x26, "IrsConfigure is an invalid size");
544
545#pragma pack(push, 1)
546struct IrsRegister {
547 IrRegistersAddress address;
548 u8 value;
549};
550static_assert(sizeof(IrsRegister) == 0x3, "IrsRegister is an invalid size");
551
552struct IrsWriteRegisters {
553 MCUCommand command;
554 MCUSubCommand sub_command;
555 u8 number_of_registers;
556 std::array<IrsRegister, 9> registers;
557 INSERT_PADDING_BYTES(0x7);
558 u8 crc;
559};
560static_assert(sizeof(IrsWriteRegisters) == 0x26, "IrsWriteRegisters is an invalid size");
561#pragma pack(pop)
562
459struct FirmwareVersion { 563struct FirmwareVersion {
460 u8 major; 564 u8 major;
461 u8 minor; 565 u8 minor;
@@ -490,6 +594,7 @@ struct JoyconCallbacks {
490 std::function<void(int, const MotionData&)> on_motion_data; 594 std::function<void(int, const MotionData&)> on_motion_data;
491 std::function<void(f32)> on_ring_data; 595 std::function<void(f32)> on_ring_data;
492 std::function<void(const std::vector<u8>&)> on_amiibo_data; 596 std::function<void(const std::vector<u8>&)> on_amiibo_data;
597 std::function<void(const std::vector<u8>&, IrsResolution)> on_camera_data;
493}; 598};
494 599
495} // namespace InputCommon::Joycon 600} // namespace InputCommon::Joycon
diff --git a/src/input_common/helpers/joycon_protocol/poller.cpp b/src/input_common/helpers/joycon_protocol/poller.cpp
index fd05d98f3..940b20b7f 100644
--- a/src/input_common/helpers/joycon_protocol/poller.cpp
+++ b/src/input_common/helpers/joycon_protocol/poller.cpp
@@ -74,10 +74,14 @@ void JoyconPoller::UpdateColor(const Color& color) {
74 callbacks.on_color_data(color); 74 callbacks.on_color_data(color);
75} 75}
76 76
77void JoyconPoller::updateAmiibo(const std::vector<u8>& amiibo_data) { 77void JoyconPoller::UpdateAmiibo(const std::vector<u8>& amiibo_data) {
78 callbacks.on_amiibo_data(amiibo_data); 78 callbacks.on_amiibo_data(amiibo_data);
79} 79}
80 80
81void JoyconPoller::UpdateCamera(const std::vector<u8>& camera_data, IrsResolution format) {
82 callbacks.on_camera_data(camera_data, format);
83}
84
81void JoyconPoller::UpdateRing(s16 value, const RingStatus& ring_status) { 85void JoyconPoller::UpdateRing(s16 value, const RingStatus& ring_status) {
82 float normalized_value = static_cast<float>(value - ring_status.default_value); 86 float normalized_value = static_cast<float>(value - ring_status.default_value);
83 if (normalized_value > 0) { 87 if (normalized_value > 0) {
diff --git a/src/input_common/helpers/joycon_protocol/poller.h b/src/input_common/helpers/joycon_protocol/poller.h
index c40fc7bca..354d41dad 100644
--- a/src/input_common/helpers/joycon_protocol/poller.h
+++ b/src/input_common/helpers/joycon_protocol/poller.h
@@ -36,7 +36,8 @@ public:
36 36
37 void UpdateColor(const Color& color); 37 void UpdateColor(const Color& color);
38 void UpdateRing(s16 value, const RingStatus& ring_status); 38 void UpdateRing(s16 value, const RingStatus& ring_status);
39 void updateAmiibo(const std::vector<u8>& amiibo_data); 39 void UpdateAmiibo(const std::vector<u8>& amiibo_data);
40 void UpdateCamera(const std::vector<u8>& amiibo_data, IrsResolution format);
40 41
41private: 42private:
42 void UpdateActiveLeftPadInput(const InputReportActive& input, 43 void UpdateActiveLeftPadInput(const InputReportActive& input,