diff --git a/app/src/main/cpp/skyline/input/npad_device.cpp b/app/src/main/cpp/skyline/input/npad_device.cpp index 004f78ca..bd02efbe 100644 --- a/app/src/main/cpp/skyline/input/npad_device.cpp +++ b/app/src/main/cpp/skyline/input/npad_device.cpp @@ -10,7 +10,14 @@ namespace skyline::input { : manager(manager), section(section), id(id), - updateEvent(std::make_shared(manager.state, false)) {} + updateEvent(std::make_shared(manager.state, false)) { + constexpr std::size_t InitializeEntryCount{19}; //!< HW initializes the first 19 entries + + ResetDeviceProperties(); + for (std::size_t i{}; i < InitializeEntryCount; ++i) { + WriteEmptyEntries(); + } + } void NpadDevice::Connect(NpadControllerType newType) { if (type == newType) { @@ -29,10 +36,11 @@ namespace skyline::input { return; } - section = {}; + ResetDeviceProperties(); controllerInfo = nullptr; - connectionState = {.connected = true}; + connectionState.raw = 0; + connectionState.connected = true; switch (newType) { case NpadControllerType::ProController: @@ -154,8 +162,7 @@ namespace skyline::input { if (type == NpadControllerType::None) return; - section = {}; - globalTimestamp = 0; + ResetDeviceProperties(); index = -1; partnerIndex = -1; @@ -164,6 +171,7 @@ namespace skyline::input { controllerInfo = nullptr; updateEvent->Signal(); + WriteEmptyEntries(); } NpadControllerInfo &NpadDevice::GetControllerInfo() { @@ -203,6 +211,36 @@ namespace skyline::input { nextEntry.status.raw = connectionState.raw; } + void NpadDevice::WriteEmptyEntries() { + NpadControllerState emptyEntry{}; + + WriteNextEntry(section.fullKeyController, emptyEntry); + WriteNextEntry(section.handheldController, emptyEntry); + WriteNextEntry(section.leftController, emptyEntry); + WriteNextEntry(section.rightController, emptyEntry); + WriteNextEntry(section.palmaController, emptyEntry); + WriteNextEntry(section.dualController, emptyEntry); + WriteNextEntry(section.defaultController, emptyEntry); + + globalTimestamp++; + } + + void NpadDevice::ResetDeviceProperties() { + // Don't reset assignment mode or ring lifo entries these values are persistent + section.header.type = NpadControllerType::None; + section.header.singleColor = {}; + section.header.leftColor = {}; + section.header.rightColor = {}; + section.header.singleColorStatus = NpadColorReadStatus::Disconnected; + section.header.dualColorStatus = NpadColorReadStatus::Disconnected; + section.deviceType.raw = 0; + section.buttonProperties.raw = 0; + section.systemProperties.raw = 0; + section.singleBatteryLevel = NpadBatteryLevel::Empty; + section.leftBatteryLevel = NpadBatteryLevel::Empty; + section.rightBatteryLevel = NpadBatteryLevel::Empty; + } + void NpadDevice::UpdateSharedMemory() { if (!connectionState.connected) return; diff --git a/app/src/main/cpp/skyline/input/npad_device.h b/app/src/main/cpp/skyline/input/npad_device.h index b4204d28..5cf8125a 100644 --- a/app/src/main/cpp/skyline/input/npad_device.h +++ b/app/src/main/cpp/skyline/input/npad_device.h @@ -145,6 +145,16 @@ namespace skyline::input { */ void WriteNextEntry(NpadControllerInfo &info, NpadControllerState entry); + /** + * @brief Writes on all ring lifo buffers a new empty entry in HID Shared Memory + */ + void WriteEmptyEntries(); + + /** + * @brief Reverts all device properties to the default state + */ + void ResetDeviceProperties(); + /** * @return The NpadControllerInfo for this controller based on its type */