From 40e5b08f7042fc3d09c4ff27767e49f8157f8417 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 18 Nov 2020 00:15:10 +0100 Subject: [PATCH] Split hidGetNpadControllerColor/PowerInfo into Single/Split variants --- nx/include/switch/services/hid.h | 14 ++++-- nx/source/services/hid.c | 82 ++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 530cfdb4..973989fd 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -842,8 +842,11 @@ u32 hidGetNpadStyleSet(u32 id); /// Gets the \ref HidNpadJoyAssignmentMode for the specified controller. HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(u32 id); -/// Gets the \ref HidNpadControllerColor for the specified controller. colors is the output array, where count is the number of entries. count must be 1 or 2: former for the main colors, latter for reading left/right colors. -Result hidGetNpadControllerColor(u32 id, HidNpadControllerColor *colors, size_t count); +/// Gets the main \ref HidNpadControllerColor for the specified controller. +Result hidGetNpadControllerColorSingle(u32 id, HidNpadControllerColor *color); + +/// Gets the left/right \ref HidNpadControllerColor for the specified controller (Joy-Con pair in dual mode). +Result hidGetNpadControllerColorSplit(u32 id, HidNpadControllerColor *color_left, HidNpadControllerColor *color_right); /// Gets the \ref HidDeviceTypeBits for the specified controller. u32 hidGetNpadDeviceType(u32 id); @@ -854,8 +857,11 @@ void hidGetNpadSystemProperties(u32 id, HidNpadSystemProperties *out); /// Gets the \ref HidNpadSystemButtonProperties for the specified controller. void hidGetNpadSystemButtonProperties(u32 id, HidNpadSystemButtonProperties *out); -/// Gets the \ref HidPowerInfo for the specified controller. info is the output array, where count is the number of entries. count must be 1 or 2: former for the main battery info, latter for reading left/right Joy-Con PowerInfo. -void hidGetNpadPowerInfo(u32 id, HidPowerInfo *info, size_t count); +/// Gets the main \ref HidPowerInfo for the specified controller. +void hidGetNpadPowerInfoSingle(u32 id, HidPowerInfo *info); + +/// Gets the left/right \ref HidPowerInfo for the specified controller (Joy-Con pair in dual mode). +void hidGetNpadPowerInfoSplit(u32 id, HidPowerInfo *info_left, HidPowerInfo *info_right); /// Gets a bitfield of AppletFooterUiAttributes for the specified Npad. /// Only available on [9.0.0+]. diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index 0f7f3b76..2d70b8f0 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -358,28 +358,43 @@ HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(u32 id) { return tmp; } -Result hidGetNpadControllerColor(u32 id, HidNpadControllerColor *colors, size_t count) { +Result hidGetNpadControllerColorSingle(u32 id, HidNpadControllerColor *color) { Result rc = _hidVerifyNpadIdType(id); - u32 tmp=0; - - if (count==0) return rc; if (R_SUCCEEDED(rc)) { HidNpad *npad = _hidNpadSharedmemGetInternalState(id); if (npad == NULL) rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); else { - tmp = count==1 ? npad->header.single_colors_descriptor : npad->header.split_colors_descriptor; + u32 tmp = npad->header.single_colors_descriptor; + if (tmp==2) rc = MAKERESULT(202, 604); + else if (tmp==1) rc = MAKERESULT(202, 603); + else if (tmp!=0) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen)); + + if (R_SUCCEEDED(rc)) + *color = npad->header.single_colors; + } + } + + return rc; +} + +Result hidGetNpadControllerColorSplit(u32 id, HidNpadControllerColor *color_left, HidNpadControllerColor *color_right) { + Result rc = _hidVerifyNpadIdType(id); + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else { + u32 tmp = npad->header.split_colors_descriptor; if (tmp==2) rc = MAKERESULT(202, 604); else if (tmp==1) rc = MAKERESULT(202, 603); else if (tmp!=0) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen)); if (R_SUCCEEDED(rc)) { - if (count==1) colors[0] = npad->header.single_colors; - else { - colors[0] = npad->header.left_colors; - colors[1] = npad->header.right_colors; - } + *color_left = npad->header.left_colors; + *color_right = npad->header.right_colors; } } } @@ -431,30 +446,45 @@ void hidGetNpadSystemButtonProperties(u32 id, HidNpadSystemButtonProperties *out if (R_FAILED(rc)) diagAbortWithResult(rc); } -void hidGetNpadPowerInfo(u32 id, HidPowerInfo *info, size_t count) { +static void _hidGetNpadPowerInfo(HidNpad *npad, HidPowerInfo *info, u32 powerInfo, u32 i) { + info->batteryCharge = atomic_load_explicit(&npad->batteryCharge[i], memory_order_acquire); + if (info->batteryCharge > 4) info->batteryCharge = 4; // sdknso would Abort when this occurs. + + info->isCharging = (powerInfo & BIT(i)) != 0; + info->powerConnected = (powerInfo & BIT(i+3)) != 0; +} + +void hidGetNpadPowerInfoSingle(u32 id, HidPowerInfo *info) { Result rc = _hidVerifyNpadIdType(id); - size_t i; - size_t indexbase; - HidNpadSystemProperties properties; - - if (count == 0) return; - if (count > 2) count = 2; - indexbase = count-1; - - hidGetNpadSystemProperties(id, &properties); if (R_SUCCEEDED(rc)) { HidNpad *npad = _hidNpadSharedmemGetInternalState(id); if (npad == NULL) rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); else { - for (i=0; ibatteryCharge[indexbase+i], memory_order_acquire); - if (info[i].batteryCharge > 4) info->batteryCharge = 4; // sdknso would Abort when this occurs. + HidNpadSystemProperties properties; + properties = atomic_load_explicit(&npad->system_properties, memory_order_acquire); - info[i].isCharging = (properties.powerInfo & BIT(indexbase+i)) != 0; - info[i].powerConnected = (properties.powerInfo & BIT(indexbase+i+3)) != 0; - } + _hidGetNpadPowerInfo(npad, info, properties.powerInfo, 0); + } + } + + if (R_FAILED(rc)) diagAbortWithResult(rc); +} + +void hidGetNpadPowerInfoSplit(u32 id, HidPowerInfo *info_left, HidPowerInfo *info_right) { + Result rc = _hidVerifyNpadIdType(id); + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else { + HidNpadSystemProperties properties; + properties = atomic_load_explicit(&npad->system_properties, memory_order_acquire); + + _hidGetNpadPowerInfo(npad, info_left, properties.powerInfo, 1); + _hidGetNpadPowerInfo(npad, info_right, properties.powerInfo, 2); } }