diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/ir/extra_hid.cpp | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/src/core/hle/service/ir/extra_hid.cpp b/src/core/hle/service/ir/extra_hid.cpp deleted file mode 100644 index e7acc17a5..000000000 --- a/src/core/hle/service/ir/extra_hid.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/alignment.h" -#include "common/bit_field.h" -#include "common/string_util.h" -#include "core/core_timing.h" -#include "core/hle/service/ir/extra_hid.h" -#include "core/settings.h" - -namespace Service { -namespace IR { - -enum class RequestID : u8 { - /** - * ConfigureHIDPolling request - * Starts HID input polling, or changes the polling interval if it is already started. - * Inputs: - * byte 0: request ID - * byte 1: polling interval in ms - * byte 2: unknown - */ - ConfigureHIDPolling = 1, - - /** - * ReadCalibrationData request - * Reads the calibration data stored in circle pad pro. - * Inputs: - * byte 0: request ID - * byte 1: expected response time in ms? - * byte 2-3: data offset (aligned to 0x10) - * byte 4-5: data size (aligned to 0x10) - */ - ReadCalibrationData = 2, - - // TODO(wwylele): there are three more request types (id = 3, 4 and 5) -}; - -enum class ResponseID : u8 { - - /** - * PollHID response - * Sends current HID status - * Output: - * byte 0: response ID - * byte 1-3: Right circle pad position. This three bytes are two little-endian 12-bit - * fields. The first one is for x-axis and the second one is for y-axis. - * byte 4: bit[0:4] battery level; bit[5] ZL button; bit[6] ZR button; bit[7] R button - * Note that for the three button fields, the bit is set when the button is NOT pressed. - * byte 5: unknown - */ - PollHID = 0x10, - - /** - * ReadCalibrationData response - * Sends the calibration data reads from circle pad pro. - * Output: - * byte 0: resonse ID - * byte 1-2: data offset (aligned to 0x10) - * byte 3-4: data size (aligned to 0x10) - * byte 5-...: calibration data - */ - ReadCalibrationData = 0x11, -}; - -ExtraHID::ExtraHID(SendFunc send_func) : IRDevice(send_func) { - LoadInputDevices(); - - // The data below was retrieved from a New 3DS - // TODO(wwylele): this data is probably writable (via request 3?) and thus should be saved to - // and loaded from somewhere. - calibration_data = std::array<u8, 0x40>{{ - // 0x00 - 0x00, 0x00, 0x08, 0x80, 0x85, 0xEB, 0x11, 0x3F, - // 0x08 - 0x85, 0xEB, 0x11, 0x3F, 0xFF, 0xFF, 0xFF, 0xF5, - // 0x10 - 0xFF, 0x00, 0x08, 0x80, 0x85, 0xEB, 0x11, 0x3F, - // 0x18 - 0x85, 0xEB, 0x11, 0x3F, 0xFF, 0xFF, 0xFF, 0x65, - // 0x20 - 0xFF, 0x00, 0x08, 0x80, 0x85, 0xEB, 0x11, 0x3F, - // 0x28 - 0x85, 0xEB, 0x11, 0x3F, 0xFF, 0xFF, 0xFF, 0x65, - // 0x30 - 0xFF, 0x00, 0x08, 0x80, 0x85, 0xEB, 0x11, 0x3F, - // 0x38 - 0x85, 0xEB, 0x11, 0x3F, 0xFF, 0xFF, 0xFF, 0x65, - }}; - - hid_polling_callback_id = - CoreTiming::RegisterEvent("ExtraHID::SendHIDStatus", [this](u64, int cycles_late) { - SendHIDStatus(); - CoreTiming::ScheduleEvent(msToCycles(hid_period) - cycles_late, - hid_polling_callback_id); - }); -} - -ExtraHID::~ExtraHID() { - OnDisconnect(); -} - -void ExtraHID::OnConnect() {} - -void ExtraHID::OnDisconnect() { - CoreTiming::UnscheduleEvent(hid_polling_callback_id, 0); -} - -void ExtraHID::HandleConfigureHIDPollingRequest(const std::vector<u8>& request) { - if (request.size() != 3) { - LOG_ERROR(Service_IR, "Wrong request size (%zu): %s", request.size(), - Common::ArrayToString(request.data(), request.size()).c_str()); - return; - } - - // Change HID input polling interval - CoreTiming::UnscheduleEvent(hid_polling_callback_id, 0); - hid_period = request[1]; - CoreTiming::ScheduleEvent(msToCycles(hid_period), hid_polling_callback_id); -} - -void ExtraHID::HandleReadCalibrationDataRequest(const std::vector<u8>& request_buf) { - struct ReadCalibrationDataRequest { - RequestID request_id; - u8 expected_response_time; - u16_le offset; - u16_le size; - }; - static_assert(sizeof(ReadCalibrationDataRequest) == 6, - "ReadCalibrationDataRequest has wrong size"); - - if (request_buf.size() != sizeof(ReadCalibrationDataRequest)) { - LOG_ERROR(Service_IR, "Wrong request size (%zu): %s", request_buf.size(), - Common::ArrayToString(request_buf.data(), request_buf.size()).c_str()); - return; - } - - ReadCalibrationDataRequest request; - std::memcpy(&request, request_buf.data(), sizeof(request)); - - const u16 offset = Common::AlignDown(request.offset, 16); - const u16 size = Common::AlignDown(request.size, 16); - - if (offset + size > calibration_data.size()) { - LOG_ERROR(Service_IR, "Read beyond the end of calibration data! (offset=%u, size=%u)", - offset, size); - return; - } - - std::vector<u8> response(5); - response[0] = static_cast<u8>(ResponseID::ReadCalibrationData); - std::memcpy(&response[1], &request.offset, sizeof(request.offset)); - std::memcpy(&response[3], &request.size, sizeof(request.size)); - response.insert(response.end(), calibration_data.begin() + offset, - calibration_data.begin() + offset + size); - Send(response); -} - -void ExtraHID::OnReceive(const std::vector<u8>& data) { - switch (static_cast<RequestID>(data[0])) { - case RequestID::ConfigureHIDPolling: - HandleConfigureHIDPollingRequest(data); - break; - case RequestID::ReadCalibrationData: - HandleReadCalibrationDataRequest(data); - break; - default: - LOG_ERROR(Service_IR, "Unknown request: %s", - Common::ArrayToString(data.data(), data.size()).c_str()); - break; - } -} - -void ExtraHID::SendHIDStatus() { - if (is_device_reload_pending.exchange(false)) - LoadInputDevices(); - - struct { - union { - BitField<0, 8, u32_le> header; - BitField<8, 12, u32_le> c_stick_x; - BitField<20, 12, u32_le> c_stick_y; - } c_stick; - union { - BitField<0, 5, u8> battery_level; - BitField<5, 1, u8> zl_not_held; - BitField<6, 1, u8> zr_not_held; - BitField<7, 1, u8> r_not_held; - } buttons; - u8 unknown; - } response; - static_assert(sizeof(response) == 6, "HID status response has wrong size!"); - - constexpr int C_STICK_CENTER = 0x800; - // TODO(wwylele): this value is not accurately measured. We currently assume that the axis can - // take values in the whole range of a 12-bit integer. - constexpr int C_STICK_RADIUS = 0x7FF; - - float x, y; - std::tie(x, y) = c_stick->GetStatus(); - - response.c_stick.header.Assign(static_cast<u8>(ResponseID::PollHID)); - response.c_stick.c_stick_x.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * x)); - response.c_stick.c_stick_y.Assign(static_cast<u32>(C_STICK_CENTER + C_STICK_RADIUS * y)); - response.buttons.battery_level.Assign(0x1F); - response.buttons.zl_not_held.Assign(!zl->GetStatus()); - response.buttons.zr_not_held.Assign(!zr->GetStatus()); - response.buttons.r_not_held.Assign(1); - response.unknown = 0; - - std::vector<u8> response_buffer(sizeof(response)); - memcpy(response_buffer.data(), &response, sizeof(response)); - Send(response_buffer); -} - -void ExtraHID::RequestInputDevicesReload() { - is_device_reload_pending.store(true); -} - -void ExtraHID::LoadInputDevices() { - zl = Input::CreateDevice<Input::ButtonDevice>( - Settings::values.buttons[Settings::NativeButton::ZL]); - zr = Input::CreateDevice<Input::ButtonDevice>( - Settings::values.buttons[Settings::NativeButton::ZR]); - c_stick = Input::CreateDevice<Input::AnalogDevice>( - Settings::values.analogs[Settings::NativeAnalog::CStick]); -} - -} // namespace IR -} // namespace Service |