From 2ad9c7655b992e09175cb792b9295b6ba22c4602 Mon Sep 17 00:00:00 2001 From: Felix-Dev Date: Mon, 5 Apr 2021 21:53:48 +0200 Subject: [PATCH 1/2] pspctrl.h: Add SceCtrlLatch API documentation. --- src/ctrl/pspctrl.h | 111 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/src/ctrl/pspctrl.h b/src/ctrl/pspctrl.h index b03dbb68..f7596de9 100644 --- a/src/ctrl/pspctrl.h +++ b/src/ctrl/pspctrl.h @@ -101,10 +101,45 @@ typedef struct SceCtrlData { unsigned char Rsrv[6]; } SceCtrlData; +/** + * This structure represents controller button latch data. + * + * With each sampling cycle, the controller service compares the new pressed & released button states + * with the previously collected pressed button states. This comparison will result in the following possible + * states for each button: + * + * • [make]: The button has just been pressed with its prior state being the released state. Transition from + * 'released' state to 'pressed' state. + * • [press]: The button is currently in the 'pressed' state. + * • [break]: The button has just been released with its prior state being the 'pressed' state. Transition from + * 'pressed' state to 'release' state. + * • [release]: The button is currently in the 'released' state. + * + * It is possible for a button to (briefly) be in two states at the same time. Valid combinations are as follows: + * + * • [make] & [press] + * • [break] & [release] + * + * In other words, if a button is in the [make] state, then it is also in the [press] state. However, this is not the case + * for the inverse. A button in the [press] state does not need to be in the [make] state. + * + * These comparison results are stored internally as latch data and can be retrieved using the APIs ::sceCtrlPeekLatch() and + * ::sceCtrlReadLatch(). ::SceCtrlPadButtons can be used to find out the state of each button. + * + * @remark The same can be accomplished by using the different sceCtrl[Read/Peek]Buffer[Positive/Negative]() APIs + * and comparing the currently collected button sampling data with the previously collected one. + * + * @see ::sceCtrlPeekLatch() + * @see ::sceCtrlReadLatch() + */ typedef struct SceCtrlLatch { + /** Button transitioned to pressed state. */ unsigned int uiMake; + /** Button transitioned to released state. */ unsigned int uiBreak; + /** Button is in the pressed state. */ unsigned int uiPress; + /** Button is in the released state. */ unsigned int uiRelease; } SceCtrlLatch; @@ -168,8 +203,84 @@ int sceCtrlReadBufferPositive(SceCtrlData *pad_data, int count); int sceCtrlReadBufferNegative(SceCtrlData *pad_data, int count); +/** + * @brief Get the latch data. + * + * This function reads the latch data collected by the controller service. At each sampling + * interval, the controller service compares the new pressed/released button states with the previously sampled pressed + * button states and stores that comparison as latch data. + * + * Compared to ::sceCtrlReadLatch(), calling this API will not result in clearing the internal latch data. As such, + * the data returned is the accumulated latch data since the last time ::sceCtrlReadLatch() was called. Consequently, + * the returned data should not be relied on whether a button is currently in a pressed or released state. + * + * @param latch_data Pointer to a ::SceCtrlLatch variable which is to receive the accumulated button latch data. + * + * @return On success, the number of times the controller service performed sampling since the last time + * ::sceCtrlReadLatch() was called. + * @return < 0 on error. + * + * @see ::SceCtrlLatch + * @see ::sceCtrlReadLatch() + */ int sceCtrlPeekLatch(SceCtrlLatch *latch_data); +/** + * @brief Get the latch data. + * + * This function reads the most recent latch data collected by the controller service. At each sampling + * interval, the controller service compares the new pressed/released button states with the previously sampled pressed + * button states and stores that comparison as latch data. + * + * Compared to ::sceCtrlPeekLatch(), calling this API will result in clearing the internal latch data. As such, + * calling code might have to explicitly wait for the controller service to update its collected latch data. + * + * @param latch_data Pointer to a ::SceCtrlLatch variable which is to receive the current button latch data. + * + * @return On success, the number of times the controller service performed sampling since the last time + * ::sceCtrlReadLatch() was called. + * @return < 0 on error. + * + * @par Example: + * @code + * SceCtrlLatch latchData; + * + * while (1) { + * // Obtain latch data + * sceCtrlReadLatch(&latchData); + * + * if (latchData.buttonMake & SCE_CTRL_CROSS) + * { + * // The Cross button has just been pressed (transition from 'released' state to 'pressed' state) + * } + * + * if (latchData.buttonPress & SCE_CTRL_SQUARE) + * { + * // The Square button is currently in the 'pressed' state + * } + * + * if (latchData.buttonBreak & SCE_CTRL_TRIANGLE) + * { + * // The Trangle button has just been released (transition from 'pressed' state to 'released' state) + * } + * + * if (latchData.buttonRelease & SCE_CTRL_CIRCLE) + * { + * // The Circle button is currently in the 'released' state + * } + * + * // As we clear the internal latch data with the ReadLatch() call, we can explicitly wait for the VBLANK interval + * // to give the controller service the time it needs to collect new latch data again. This guarantees the next call + * // to sceCtrlReadLatch() will return collected data again. + * // + * // Note: The sceCtrlReadBuffer*() APIs are implicitly waiting for a VBLANK interval if necessary. + * sceDisplayWaitVBlank(); + * } + * @endcode + * + * @see ::SceCtrlLatch + * @see ::sceCtrlPeekLatch() + */ int sceCtrlReadLatch(SceCtrlLatch *latch_data); /** From 34773491be9fda869edb4a7b17297cd639ecfad0 Mon Sep 17 00:00:00 2001 From: Felix-Dev Date: Mon, 5 Apr 2021 21:57:01 +0200 Subject: [PATCH 2/2] Fix typo and adjust button macros --- src/ctrl/pspctrl.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ctrl/pspctrl.h b/src/ctrl/pspctrl.h index f7596de9..7d956070 100644 --- a/src/ctrl/pspctrl.h +++ b/src/ctrl/pspctrl.h @@ -249,22 +249,22 @@ int sceCtrlPeekLatch(SceCtrlLatch *latch_data); * // Obtain latch data * sceCtrlReadLatch(&latchData); * - * if (latchData.buttonMake & SCE_CTRL_CROSS) + * if (latchData.buttonMake & PSP_CTRL_CROSS) * { * // The Cross button has just been pressed (transition from 'released' state to 'pressed' state) * } * - * if (latchData.buttonPress & SCE_CTRL_SQUARE) + * if (latchData.buttonPress & PSP_CTRL_SQUARE) * { * // The Square button is currently in the 'pressed' state * } * - * if (latchData.buttonBreak & SCE_CTRL_TRIANGLE) + * if (latchData.buttonBreak & PSP_CTRL_TRIANGLE) * { - * // The Trangle button has just been released (transition from 'pressed' state to 'released' state) + * // The Triangle button has just been released (transition from 'pressed' state to 'released' state) * } * - * if (latchData.buttonRelease & SCE_CTRL_CIRCLE) + * if (latchData.buttonRelease & PSP_CTRL_CIRCLE) * { * // The Circle button is currently in the 'released' state * }