230 lines
8 KiB
Nim
230 lines
8 KiB
Nim
## *
|
|
## @file pad.h
|
|
## @brief Simple wrapper for the HID Npad API.
|
|
## @author fincs
|
|
## @copyright libnx Authors
|
|
##
|
|
|
|
import
|
|
../types, ../services/hid
|
|
|
|
## / Mask including all existing controller IDs.
|
|
|
|
const
|
|
PAD_ANY_ID_MASK* = 0x1000100FF'u
|
|
|
|
## / Pad state object.
|
|
|
|
type
|
|
PadState* {.bycopy.} = object
|
|
idMask*: U8
|
|
activeIdMask*: U8
|
|
readHandheld*: bool
|
|
activeHandheld*: bool
|
|
styleSet*: U32
|
|
attributes*: U32
|
|
buttonsCur*: U64
|
|
buttonsOld*: U64
|
|
sticks*: array[2, HidAnalogStickState]
|
|
gcTriggers*: array[2, U32]
|
|
|
|
|
|
## / Pad button repeater state object.
|
|
|
|
type
|
|
PadRepeater* {.bycopy.} = object
|
|
buttonMask*: U64
|
|
counter*: S32
|
|
delay*: U16
|
|
repeat*: U16
|
|
|
|
|
|
## *
|
|
## @brief Configures the input layout supported by the application.
|
|
## @param[in] max_players The maximum supported number of players (1 to 8).
|
|
## @param[in] style_set Bitfield of supported controller styles (see \ref HidNpadStyleTag).
|
|
##
|
|
|
|
proc padConfigureInput*(maxPlayers: U32; styleSet: U32) {.cdecl,
|
|
importc: "padConfigureInput".}
|
|
## *
|
|
## @brief Initializes a \ref PadState object to read input from one or more controller input sources.
|
|
## @param[in] _pad Pointer to \ref PadState.
|
|
## @remarks This is a variadic macro, pass the \ref HidNpadIdType value of each controller to add to the set.
|
|
##
|
|
|
|
|
|
## @brief Same as \ref padInitialize, but taking a bitfield of controller IDs directly.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @param[in] mask Bitfield of controller IDs (each bit's position indicates a different \ref HidNpadIdType value).
|
|
proc padInitializeWithMask*(pad: ptr PadState, mask: U64) {.cdecl, importc: "padInitializeWithMask".}
|
|
|
|
proc padInitialize*(pad: ptr PadState, padIds: varargs[HidNpadIdType]) {.inline, cdecl.} =
|
|
var mask: U64 = 0
|
|
for i in 0..<padIds.len:
|
|
mask = mask or (1'u64 shl padIds[i].uint64)
|
|
padInitializeWithMask(pad, mask)
|
|
|
|
## *
|
|
## @brief Same as \ref padInitialize, but including every single controller input source.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @remark Use this function if you want to accept input from any controller.
|
|
##
|
|
|
|
proc padInitializeAny*(pad: ptr PadState) {.inline, cdecl.} =
|
|
padInitializeWithMask(pad, Pad_Any_Id_Mask)
|
|
|
|
## *
|
|
## @brief Same as \ref padInitialize, but including \ref HidNpadIdType_No1 and \ref HidNpadIdType_Handheld.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @remark Use this function if you just want to accept input for a single-player application.
|
|
##
|
|
|
|
proc padInitializeDefault*(pad: ptr PadState) {.inline, cdecl.} =
|
|
padInitialize(pad, HidNpadIdTypeNo1, HidNpadIdTypeHandheld)
|
|
|
|
## *
|
|
## @brief Updates pad state by reading from the controller input sources specified during initialization.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
##
|
|
|
|
proc padUpdate*(pad: ptr PadState) {.cdecl, importc: "padUpdate".}
|
|
## *
|
|
## @brief Retrieves whether \ref HidNpadIdType_Handheld is an active input source (i.e. it was possible to read from it).
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Boolean value.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padIsHandheld*(pad: ptr PadState): bool {.inline, cdecl.} =
|
|
return pad.activeHandheld
|
|
|
|
## *
|
|
## @brief Retrieves whether the specified controller is an active input source (i.e. it was possible to read from it).
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @param[in] id ID of the controller input source (see \ref HidNpadIdType)
|
|
## @return Boolean value.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padIsNpadActive*(pad: ptr PadState; id: HidNpadIdType): bool {.inline, cdecl.} =
|
|
if id <= HidNpadIdTypeNo8:
|
|
return bool(pad.activeIdMask and (bit(id.uint8)))
|
|
elif id == HidNpadIdTypeHandheld:
|
|
return pad.activeHandheld
|
|
else:
|
|
return false
|
|
|
|
## *
|
|
## @brief Retrieves the set of input styles supported by the selected controller input sources.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Bitfield of \ref HidNpadStyleTag.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetStyleSet*(pad: ptr PadState): U32 {.inline, cdecl.} =
|
|
return pad.styleSet
|
|
|
|
## *
|
|
## @brief Retrieves the set of attributes reported by the system for the selected controller input sources.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Bitfield of \ref HidNpadAttribute.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetAttributes*(pad: ptr PadState): U32 {.inline, cdecl.} =
|
|
return pad.attributes
|
|
|
|
## *
|
|
## @brief Retrieves whether any of the selected controller input sources is connected.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Boolean value.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padIsConnected*(pad: ptr PadState): bool {.inline, cdecl.} =
|
|
return bool(pad.attributes and HidNpadAttributeIsConnected.uint32)
|
|
|
|
## *
|
|
## @brief Retrieves the current set of pressed buttons across all selected controller input sources.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Bitfield of \ref HidNpadButton.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetButtons*(pad: ptr PadState): U64 {.inline, cdecl.} =
|
|
return pad.buttonsCur
|
|
|
|
## *
|
|
## @brief Retrieves the set of buttons that are newly pressed.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Bitfield of \ref HidNpadButton.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetButtonsDown*(pad: ptr PadState): U64 {.inline, cdecl.} =
|
|
return not pad.buttonsOld and pad.buttonsCur
|
|
|
|
## *
|
|
## @brief Retrieves the set of buttons that are newly released.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @return Bitfield of \ref HidNpadButton.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetButtonsUp*(pad: ptr PadState): U64 {.inline, cdecl.} =
|
|
return pad.buttonsOld and not pad.buttonsCur
|
|
|
|
## *
|
|
## @brief Retrieves the position of an analog stick in a controller.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @param[in] i ID of the analog stick to read (0=left, 1=right).
|
|
## @return \ref HidAnalogStickState.
|
|
## @remark \ref padUpdate must have been previously called.
|
|
##
|
|
|
|
proc padGetStickPos*(pad: ptr PadState; i: cuint): HidAnalogStickState {.inline, cdecl.} =
|
|
return pad.sticks[i]
|
|
|
|
## *
|
|
## @brief Retrieves the position of an analog trigger in a GameCube controller.
|
|
## @param[in] pad Pointer to \ref PadState.
|
|
## @param[in] i ID of the analog trigger to read (0=left, 1=right).
|
|
## @return Analog trigger position (range is 0 to 0x7fff).
|
|
## @remark \ref padUpdate must have been previously called.
|
|
## @remark \ref HidNpadStyleTag_NpadGc must have been previously configured as a supported style in \ref padConfigureInput for GC trigger data to be readable.
|
|
##
|
|
|
|
proc padGetGcTriggerPos*(pad: ptr PadState; i: cuint): U32 {.inline, cdecl.} =
|
|
return pad.gcTriggers[i]
|
|
|
|
## *
|
|
## @brief Initializes a \ref PadRepeater object with the specified settings.
|
|
## @param[in] r Pointer to \ref PadRepeater.
|
|
## @param[in] delay Number of input updates between button presses being first detected and them being considered for repeat.
|
|
## @param[in] repeat Number of input updates between autogenerated repeat button presses.
|
|
##
|
|
|
|
proc padRepeaterInitialize*(r: ptr PadRepeater; delay: U16; repeat: U16) {.inline, cdecl.} =
|
|
r.buttonMask = 0
|
|
r.counter = 0
|
|
r.delay = delay
|
|
r.repeat = repeat
|
|
|
|
## *
|
|
## @brief Updates pad repeat state.
|
|
## @param[in] r Pointer to \ref PadRepeater.
|
|
## @param[in] button_mask Bitfield of currently pressed \ref HidNpadButton that will be considered for repeat.
|
|
##
|
|
|
|
proc padRepeaterUpdate*(r: ptr PadRepeater; buttonMask: U64) {.cdecl,
|
|
importc: "padRepeaterUpdate".}
|
|
## *
|
|
## @brief Retrieves the set of buttons that are being repeated according to the parameters specified in \ref padRepeaterInitialize.
|
|
## @param[in] r Pointer to \ref PadRepeater.
|
|
## @return Bitfield of \ref HidNpadButton.
|
|
## @remark It is suggested to bitwise-OR the return value of this function with that of \ref padGetButtonsDown.
|
|
##
|
|
|
|
proc padRepeaterGetButtons*(r: ptr PadRepeater): U64 {.inline, cdecl.} =
|
|
return if r.counter == 0: r.buttonMask else: 0
|