diff --git a/CMakeLists.txt b/CMakeLists.txt index d21f030..5abe316 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,6 +244,7 @@ add_library(boo lib/inputdev/CafeProPad.cpp include/boo/inputdev/CafeProPad.hpp lib/inputdev/RevolutionPad.cpp include/boo/inputdev/RevolutionPad.hpp lib/inputdev/DolphinSmashAdapter.cpp include/boo/inputdev/DolphinSmashAdapter.hpp + lib/inputdev/NintendoPowerA.cpp include/boo/inputdev/NintendoPowerA.hpp lib/inputdev/DualshockPad.cpp include/boo/inputdev/DualshockPad.hpp include/boo/inputdev/XInputPad.hpp lib/inputdev/GenericPad.cpp include/boo/inputdev/GenericPad.hpp diff --git a/InputDeviceClasses.cpp b/InputDeviceClasses.cpp index 5295ce1..6f72a7b 100644 --- a/InputDeviceClasses.cpp +++ b/InputDeviceClasses.cpp @@ -3,6 +3,7 @@ #include "boo/inputdev/DualshockPad.hpp" #include "boo/inputdev/GenericPad.hpp" #include "boo/inputdev/XInputPad.hpp" +#include "boo/inputdev/NintendoPowerA.hpp" namespace boo { @@ -12,6 +13,7 @@ const DeviceSignature BOO_DEVICE_SIGS[] = DEVICE_SIG(DolphinSmashAdapter, 0x57e, 0x337, DeviceType::USB), DEVICE_SIG(DualshockPad, 0x54c, 0x268, DeviceType::HID), DEVICE_SIG(GenericPad, 0, 0, DeviceType::HID), + DEVICE_SIG(NintendoPowerA, 0x20D6, 0xA711, DeviceType::USB), DEVICE_SIG(XInputPad, 0, 0, DeviceType::XInput), DEVICE_SIG_SENTINEL() }; diff --git a/include/boo/boo.hpp b/include/boo/boo.hpp index f90c8a3..879e134 100644 --- a/include/boo/boo.hpp +++ b/include/boo/boo.hpp @@ -7,6 +7,7 @@ #include "inputdev/DolphinSmashAdapter.hpp" #include "inputdev/DualshockPad.hpp" #include "inputdev/GenericPad.hpp" +#include "inputdev/NintendoPowerA.hpp" #include "graphicsdev/IGraphicsCommandQueue.hpp" #include "graphicsdev/IGraphicsDataFactory.hpp" #include "DeferredWindowEvents.hpp" diff --git a/include/boo/inputdev/NintendoPowerA.hpp b/include/boo/inputdev/NintendoPowerA.hpp new file mode 100644 index 0000000..e5d46b6 --- /dev/null +++ b/include/boo/inputdev/NintendoPowerA.hpp @@ -0,0 +1,57 @@ +#ifndef NINTENDOPOWERA_HPP +#define NINTENDOPOWERA_HPP +#include "DeviceBase.hpp" +#include "boo/System.hpp" + +namespace boo +{ +struct NintendoPowerAState +{ + uint8_t y : 1; + uint8_t b : 1; + uint8_t a : 1; + uint8_t x : 1; + uint8_t l : 1; + uint8_t r : 1; + uint8_t zl : 1; + uint8_t zr : 1; + uint8_t minus : 1; + uint8_t plus : 1; + uint8_t stickL : 1; + uint8_t stickR : 1; + uint8_t home : 1; + uint8_t capture : 1; + uint8_t dPad; + uint8_t leftX; + uint8_t leftY; + uint8_t rightX; + uint8_t rightY; + bool operator==(const NintendoPowerAState& other); + bool operator!=(const NintendoPowerAState& other); +}; + +class NintendoPowerA; +struct INintendoPowerACallback +{ + virtual void controllerDisconnected() {} + virtual void controllerUpdate(const NintendoPowerAState& state) {} +}; + +class NintendoPowerA final : public DeviceBase +{ + INintendoPowerACallback* m_callback = nullptr; + NintendoPowerAState m_last; + void deviceDisconnected(); + void initialCycle(); + void transferCycle(); + void finalCycle(); + void receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message); +public: + NintendoPowerA(DeviceToken*); + ~NintendoPowerA(); + + void setCallback(INintendoPowerACallback* cb) { m_callback = cb; } +}; +} + +#endif // NINTENDOPWERA_HPP diff --git a/lib/inputdev/NintendoPowerA.cpp b/lib/inputdev/NintendoPowerA.cpp new file mode 100644 index 0000000..7d278eb --- /dev/null +++ b/lib/inputdev/NintendoPowerA.cpp @@ -0,0 +1,53 @@ +#include "boo/inputdev/NintendoPowerA.hpp" +#include +namespace boo +{ +NintendoPowerA::NintendoPowerA(DeviceToken* token) + : DeviceBase(token) +{ + +} + +NintendoPowerA::~NintendoPowerA() +{ +} + +void NintendoPowerA::deviceDisconnected() +{ + if (m_callback) + m_callback->controllerDisconnected(); +} + +void NintendoPowerA::initialCycle() {} + +void NintendoPowerA::transferCycle() +{ + uint8_t payload[8]; + size_t recvSz = receiveUSBInterruptTransfer(payload, sizeof(payload)); + if (recvSz != 8) + return; + + NintendoPowerAState state = *reinterpret_cast(&payload); + + if (state != m_last && m_callback) + m_callback->controllerUpdate(state); + m_last = state; +} + +void NintendoPowerA::finalCycle() {} + +void NintendoPowerA::receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) +{ +} + +bool NintendoPowerAState::operator==(const NintendoPowerAState &other) +{ + return !memcmp(this, &other, sizeof(NintendoPowerAState)); +} + +bool NintendoPowerAState::operator!=(const NintendoPowerAState &other) +{ + return memcmp(this, &other, sizeof(NintendoPowerAState)); +} + +} diff --git a/test/main.cpp b/test/main.cpp index 8e75c87..00324e2 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -105,17 +105,34 @@ class GenericPadCallback : public IGenericPadCallback } }; +class NintendoPowerACallback : public INintendoPowerACallback +{ + void controllerDisconnected() + { + fprintf(stderr, "CONTROLLER DISCONNECTED\n"); + } + void controllerUpdate(const NintendoPowerAState& state) + { + fprintf(stderr, "%i %i\n" + "%i %i\n", + state.leftX, state.leftY, + state.rightX, state.rightY); + } +}; + class TestDeviceFinder : public DeviceFinder { std::shared_ptr m_smashAdapter; + std::shared_ptr m_nintendoPowerA; std::shared_ptr m_ds3; std::shared_ptr m_generic; DolphinSmashAdapterCallback m_cb; + NintendoPowerACallback m_nintendoPowerACb; DualshockPadCallback m_ds3CB; GenericPadCallback m_genericCb; public: TestDeviceFinder() - : DeviceFinder({typeid(DolphinSmashAdapter), typeid(GenericPad)}) + : DeviceFinder({typeid(DolphinSmashAdapter), typeid(NintendoPowerA), typeid(GenericPad)}) {} void deviceConnected(DeviceToken& tok) { @@ -126,16 +143,24 @@ public: m_smashAdapter->startRumble(0); return; } + m_nintendoPowerA = std::dynamic_pointer_cast(tok.openAndGetDevice()); + if (m_nintendoPowerA) + { + m_nintendoPowerA->setCallback(&m_nintendoPowerACb); + return; + } m_ds3 = std::dynamic_pointer_cast(tok.openAndGetDevice()); if (m_ds3) { m_ds3->setCallback(&m_ds3CB); m_ds3->setLED(EDualshockLED::LED_1); + return; } m_generic = std::dynamic_pointer_cast(tok.openAndGetDevice()); if (m_generic) { m_generic->setCallback(&m_genericCb); + return; } } void deviceDisconnected(DeviceToken&, DeviceBase* device) @@ -146,6 +171,8 @@ public: m_ds3.reset(); if (m_generic.get() == device) m_generic.reset(); + if (m_nintendoPowerA.get() == device) + m_nintendoPowerA.reset(); } };