Add friendly input handling and add user retrieval
This commit is contained in:
parent
62539c5477
commit
ae67cc15d3
6 changed files with 522 additions and 16 deletions
|
|
@ -1,8 +1,10 @@
|
||||||
|
import sets, strutils
|
||||||
import libnx/graphics
|
import libnx/graphics
|
||||||
import libnx/wrapper/hid
|
import libnx/wrapper/hid
|
||||||
import libnx/wrapper/console
|
import libnx/wrapper/console
|
||||||
import libnx/ext/integer128
|
import libnx/ext/integer128
|
||||||
import libnx/account
|
import libnx/account
|
||||||
|
import libnx/input
|
||||||
import libnx/app
|
import libnx/app
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
|
|
@ -25,10 +27,22 @@ proc main() =
|
||||||
let msg = getCurrentExceptionMsg()
|
let msg = getCurrentExceptionMsg()
|
||||||
echo "\x1b[6;2H" & msg
|
echo "\x1b[6;2H" & msg
|
||||||
|
|
||||||
mainLoop:
|
try:
|
||||||
let keysDown = hidKeysDown(CONTROLLER_P1_AUTO)
|
let users = listAllUsers()
|
||||||
|
echo ""
|
||||||
|
echo " There are $# users:" % $users.len()
|
||||||
|
for user in users:
|
||||||
|
echo " User: " & user.username
|
||||||
|
except AccountUserListError:
|
||||||
|
let msg = getCurrentExceptionMsg()
|
||||||
|
echo msg
|
||||||
|
|
||||||
if (keysDown and KEY_PLUS.uint64) > 0.uint64:
|
|
||||||
|
|
||||||
|
mainLoop:
|
||||||
|
let keysDown = keysDown(Controller.P1_AUTO)
|
||||||
|
|
||||||
|
if ControllerKey.Plus in keysDown:
|
||||||
break
|
break
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ defines = true
|
||||||
defines = true
|
defines = true
|
||||||
search.static_assert = "static_assert"
|
search.static_assert = "static_assert"
|
||||||
replace.static_assert = "// static_assert"
|
replace.static_assert = "// static_assert"
|
||||||
|
search.touch = "touchPosition"
|
||||||
|
replace.touch = "TouchPosition"
|
||||||
|
|
||||||
[ipc.h]
|
[ipc.h]
|
||||||
defines = true
|
defines = true
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ type
|
||||||
AccountInitError* = object of AccountError
|
AccountInitError* = object of AccountError
|
||||||
AccountImageSizeError* = object of AccountError
|
AccountImageSizeError* = object of AccountError
|
||||||
AccountUserProfileError* = object of AccountError
|
AccountUserProfileError* = object of AccountError
|
||||||
|
AccountUserCountError* = object of AccountError
|
||||||
|
AccountUserListError* = object of AccountError
|
||||||
AccountUserNotSelectedError* = object of AccountError
|
AccountUserNotSelectedError* = object of AccountError
|
||||||
AccountUserDataError* = object of AccountError
|
AccountUserDataError* = object of AccountError
|
||||||
AccountActiveUserError* = object of AccountError
|
AccountActiveUserError* = object of AccountError
|
||||||
|
|
@ -120,6 +122,32 @@ proc loadImage*(user: User): AccountImage =
|
||||||
proc userID*(user: User): string =
|
proc userID*(user: User): string =
|
||||||
$user.id
|
$user.id
|
||||||
|
|
||||||
|
proc getUser*(userID: u128): User =
|
||||||
|
ensureEnabled()
|
||||||
|
result = new(User)
|
||||||
|
|
||||||
|
result.id = userID
|
||||||
|
result.selected = false
|
||||||
|
|
||||||
|
var
|
||||||
|
prof: AccountProfile = getProfileHelper(userID)
|
||||||
|
userData: AccountUserData
|
||||||
|
profBase: AccountProfileBase
|
||||||
|
|
||||||
|
let res = accountProfileGet(prof.addr, userData.addr, profBase.addr).newResult
|
||||||
|
|
||||||
|
if res.failed:
|
||||||
|
raiseEx(AccountUserDataError, "Error, could not get user data: " & res.description)
|
||||||
|
|
||||||
|
result.username = profBase.username.join("")
|
||||||
|
result.lastEdited = profBase.lastEditTimestamp
|
||||||
|
result.iconID = userData.iconID
|
||||||
|
result.iconBgColorID = userData.iconBackgroundColorID
|
||||||
|
result.miiID = userData.miiID
|
||||||
|
|
||||||
|
prof.close()
|
||||||
|
|
||||||
|
|
||||||
proc getActiveUser*(): User =
|
proc getActiveUser*(): User =
|
||||||
ensureEnabled()
|
ensureEnabled()
|
||||||
result = new(User)
|
result = new(User)
|
||||||
|
|
@ -171,3 +199,31 @@ proc getProfile*(user: User): Profile =
|
||||||
|
|
||||||
result.service = newService(prof.s)
|
result.service = newService(prof.s)
|
||||||
prof.close()
|
prof.close()
|
||||||
|
|
||||||
|
|
||||||
|
proc getUserCount*(): int32 =
|
||||||
|
var count: int32
|
||||||
|
let res = accountGetUserCount(count.addr).newResult
|
||||||
|
if res.failed:
|
||||||
|
raiseEx(
|
||||||
|
AccountUserCountError,
|
||||||
|
"Error, could not get user count: " & res.description
|
||||||
|
)
|
||||||
|
result = count
|
||||||
|
|
||||||
|
|
||||||
|
proc listAllUsers*(): seq[User] =
|
||||||
|
result = @[]
|
||||||
|
|
||||||
|
let numUsers = getUserCount()
|
||||||
|
var userIDs: array[ACC_USER_LIST_SIZE, u128]
|
||||||
|
let res = accountListAllUsers(userIDs[0].addr).newResult
|
||||||
|
|
||||||
|
if res.failed:
|
||||||
|
raiseEx(
|
||||||
|
AccountUserListError,
|
||||||
|
"Error, could not list users: " & res.description
|
||||||
|
)
|
||||||
|
|
||||||
|
for i in 0 ..< numUsers:
|
||||||
|
result.add(getUser(userIDs[i]))
|
||||||
|
|
|
||||||
346
src/libnx/input.nim
Normal file
346
src/libnx/input.nim
Normal file
|
|
@ -0,0 +1,346 @@
|
||||||
|
import macros, strutils, sets
|
||||||
|
import libnx/wrapper/hid
|
||||||
|
from libnx/wrapper/types import BIT
|
||||||
|
import libnx/utils
|
||||||
|
import libnx/results
|
||||||
|
import libnx/service
|
||||||
|
import libnx/results
|
||||||
|
|
||||||
|
niceify(HidMouseButton, "Hid:MOUSE_")
|
||||||
|
niceify(HidKeyboardModifier, "Hid:KBD_MOD_")
|
||||||
|
niceify(HidKeyboardScancode, "HidKeyboardScancode:KeyboardKey:KBD_:")
|
||||||
|
niceify(HidControllerType, "Hid:TYPE_")
|
||||||
|
niceify(HidControllerLayoutType, "Hid:LAYOUT_")
|
||||||
|
niceify(HidControllerColorDescription, "Hid:COLORS_")
|
||||||
|
niceify(HidControllerKeys, "HidControllerKeys:ControllerKey:KEY_:")
|
||||||
|
niceify(HidControllerJoystick, "Hid:JOYSTICK_")
|
||||||
|
niceify(HidControllerID, "HidControllerID:Controller:CONTROLLER_:")
|
||||||
|
|
||||||
|
export TouchPosition, JoystickPosition, MousePosition
|
||||||
|
export JOYSTICK_MAX, JOYSTICK_MIN
|
||||||
|
|
||||||
|
type
|
||||||
|
InputError* = object of Exception
|
||||||
|
ControllerSelectError* = object of InputError
|
||||||
|
|
||||||
|
TouchScreenHeader* = ref object
|
||||||
|
timestampTicks*: uint64
|
||||||
|
numEntries*: uint64
|
||||||
|
latestEntry*: uint64
|
||||||
|
maxEntryIndex*: uint64
|
||||||
|
timestamp*: uint64
|
||||||
|
|
||||||
|
TouchScreenEntryHeader* = ref object
|
||||||
|
timestamp*: uint64
|
||||||
|
numTouches*: uint64
|
||||||
|
|
||||||
|
TouchScreenEntryTouch* = ref object
|
||||||
|
timestamp*: uint64
|
||||||
|
padding*: uint32
|
||||||
|
touchIndex*: uint32
|
||||||
|
x*: uint32
|
||||||
|
y*: uint32
|
||||||
|
diameterX*: uint32
|
||||||
|
diameterY*: uint32
|
||||||
|
angle*: uint32
|
||||||
|
padding2*: uint32
|
||||||
|
|
||||||
|
TouchScreenEntry* = ref object
|
||||||
|
header*: TouchScreenEntryHeader
|
||||||
|
touches*: Buffer[HidTouchScreenEntryTouch]
|
||||||
|
unk*: uint64
|
||||||
|
|
||||||
|
TouchScreen* = ref object
|
||||||
|
header*: TouchScreenHeader
|
||||||
|
entries*: Buffer[HidTouchScreenEntry]
|
||||||
|
padding*: Buffer[uint8]
|
||||||
|
|
||||||
|
MouseHeader* = ref object
|
||||||
|
timestampTicks*: uint64
|
||||||
|
numEntries*: uint64
|
||||||
|
latestEntry*: uint64
|
||||||
|
maxEntryIndex*: uint64
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
MouseEntry* = ref object
|
||||||
|
timestamp*: uint64
|
||||||
|
timestamp2*: uint64
|
||||||
|
position*: MousePosition
|
||||||
|
buttons*: uint64
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
Mouse* = ref object
|
||||||
|
header*: MouseHeader
|
||||||
|
entries*: Buffer[MouseEntry]
|
||||||
|
padding*: Buffer[uint8]
|
||||||
|
|
||||||
|
KeyboardHeader* = ref object
|
||||||
|
timestampTicks*: uint64
|
||||||
|
numEntries*: uint64
|
||||||
|
latestEntry*: uint64
|
||||||
|
maxEntryIndex*: uint64
|
||||||
|
|
||||||
|
KeyboardEntry* = ref object
|
||||||
|
timestamp*: uint64
|
||||||
|
timestamp2*: uint64
|
||||||
|
modifier*: uint64
|
||||||
|
keys*: Buffer[uint32]
|
||||||
|
|
||||||
|
|
||||||
|
KeyboardSection* = ref object
|
||||||
|
header*: KeyboardHeader
|
||||||
|
entries*: array[17, KeyboardEntry]
|
||||||
|
padding*: array[0x00000028, uint8]
|
||||||
|
|
||||||
|
ControllerMAC* = object
|
||||||
|
timestamp*: uint64
|
||||||
|
mac*: array[0x00000008, uint8]
|
||||||
|
unk*: uint64
|
||||||
|
timestamp2*: uint64
|
||||||
|
|
||||||
|
ControllerHeader* = object
|
||||||
|
`type`* {.importc: "type".}: uint32
|
||||||
|
isHalf* {.importc: "isHalf".}: uint32
|
||||||
|
singleColorsDescriptor* {.importc: "singleColorsDescriptor".}: uint32
|
||||||
|
singleColorBody* {.importc: "singleColorBody".}: uint32
|
||||||
|
singleColorButtons* {.importc: "singleColorButtons".}: uint32
|
||||||
|
splitColorsDescriptor* {.importc: "splitColorsDescriptor".}: uint32
|
||||||
|
leftColorBody* {.importc: "leftColorBody".}: uint32
|
||||||
|
leftColorButtons* {.importc: "leftColorButtons".}: uint32
|
||||||
|
rightColorBody* {.importc: "rightColorBody".}: uint32
|
||||||
|
rightColorbuttons* {.importc: "rightColorbuttons".}: uint32
|
||||||
|
|
||||||
|
|
||||||
|
ControllerLayoutHeader* = object
|
||||||
|
timestampTicks* {.importc: "timestampTicks".}: uint64
|
||||||
|
numEntries* {.importc: "numEntries".}: uint64
|
||||||
|
latestEntry* {.importc: "latestEntry".}: uint64
|
||||||
|
maxEntryIndex* {.importc: "maxEntryIndex".}: uint64
|
||||||
|
|
||||||
|
|
||||||
|
HidControllerInputEntry* = object
|
||||||
|
timestamp* {.importc: "timestamp".}: uint64
|
||||||
|
timestamp_2* {.importc: "timestamp_2".}: uint64
|
||||||
|
buttons* {.importc: "buttons".}: uint64
|
||||||
|
joysticks* {.importc: "joysticks".}: array[JOYSTICK_NUM_STICKS, JoystickPosition]
|
||||||
|
connectionState* {.importc: "connectionState".}: uint64
|
||||||
|
|
||||||
|
|
||||||
|
ControllerLayoutSection* = ref object
|
||||||
|
header*: ControllerLayoutHeader
|
||||||
|
entries* {.importc: "entries".}: array[17, HidControllerInputEntry]
|
||||||
|
|
||||||
|
|
||||||
|
ControllerSection* = ref object
|
||||||
|
header* {.importc: "header".}: ControllerHeader
|
||||||
|
layouts* {.importc: "layouts".}: Buffer[ControllerLayoutSection]
|
||||||
|
unk_1*: Buffer[uint8]
|
||||||
|
macLeft*: HidControllerMAC
|
||||||
|
macRight*: HidControllerMAC
|
||||||
|
unk_2* {.importc: "unk_2".}: array[0x00000DF8, uint8]
|
||||||
|
|
||||||
|
|
||||||
|
InputSharedMemory* = ref object
|
||||||
|
header*: Buffer[uint8]
|
||||||
|
touchscreen*: TouchScreen
|
||||||
|
mouse*: Mouse
|
||||||
|
keyboard*: KeyboardSection
|
||||||
|
controllerSerials*: Buffer[uint8]
|
||||||
|
controllers*: Buffer[ControllerSection]
|
||||||
|
|
||||||
|
VibrationDeviceInfo* = ref object
|
||||||
|
unk_x0*: uint32
|
||||||
|
unk_x4*: uint32 ## /< 0x1 for left-joycon, 0x2 for right-joycon.
|
||||||
|
|
||||||
|
VibrationValue* = ref object
|
||||||
|
ampLow*: float ## /< Low Band amplitude. 1.0f: Max amplitude.
|
||||||
|
freqLow*: float ## /< Low Band frequency in Hz.
|
||||||
|
ampHigh*: float ## /< High Band amplitude. 1.0f: Max amplitude.
|
||||||
|
freqHigh*: float ## /< High Band frequency in Hz.
|
||||||
|
|
||||||
|
|
||||||
|
proc init*(): Result = hidInitialize().newResult
|
||||||
|
proc exit*() = hidExit()
|
||||||
|
proc reset*() = hidReset()
|
||||||
|
|
||||||
|
proc getSessionService*(): Service =
|
||||||
|
newService(hidGetSessionService()[])
|
||||||
|
|
||||||
|
proc getSharedMemory*(): ptr HidSharedMemory =
|
||||||
|
result = cast[ptr HidSharedMemory](hidGetSharedMemAddr())
|
||||||
|
|
||||||
|
proc setControllerLayout*(id: Controller, layoutType: ControllerLayoutType) =
|
||||||
|
hidSetControllerLayout(HidControllerID(id), HidControllerLayoutType(layoutType))
|
||||||
|
|
||||||
|
proc getControllerLayout*(id: Controller): ControllerLayoutType =
|
||||||
|
hidGetControllerLayout(HidControllerID(id)).ControllerLayoutType
|
||||||
|
|
||||||
|
proc scanInput*() = scanInput()
|
||||||
|
|
||||||
|
proc keysHeld*(id: Controller): HashSet[ControllerKey] =
|
||||||
|
result = initSet[ControllerKey]()
|
||||||
|
|
||||||
|
var raw = hidKeysHeld(HidControllerID(id))
|
||||||
|
for i in ControllerKey.low.int ..< ControllerKey.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(ControllerKey(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
proc keysDown*(id: Controller): HashSet[ControllerKey] =
|
||||||
|
result = initSet[ControllerKey]()
|
||||||
|
|
||||||
|
var raw = hidKeysDown(HidControllerID(id))
|
||||||
|
for i in ControllerKey.low.int ..< ControllerKey.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(ControllerKey(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
proc keysUp*(id: Controller): HashSet[ControllerKey] =
|
||||||
|
result = initSet[ControllerKey]()
|
||||||
|
|
||||||
|
var raw = hidKeysUp(HidControllerID(id))
|
||||||
|
for i in ControllerKey.low.int ..< ControllerKey.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(ControllerKey(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
proc mouseButtonsHeld*(): HashSet[MouseButton] =
|
||||||
|
result = initSet[MouseButton]()
|
||||||
|
|
||||||
|
var raw = hidMouseButtonsHeld()
|
||||||
|
for i in MouseButton.low.int ..< MouseButton.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(MouseButton(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
|
||||||
|
proc mouseButtonsDown*(): HashSet[MouseButton] =
|
||||||
|
result = initSet[MouseButton]()
|
||||||
|
|
||||||
|
var raw = hidMouseButtonsDown()
|
||||||
|
for i in MouseButton.low.int ..< MouseButton.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(MouseButton(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
proc mouseButtonsUp*(): HashSet[MouseButton] =
|
||||||
|
result = initSet[MouseButton]()
|
||||||
|
|
||||||
|
var raw = hidMouseButtonsUp()
|
||||||
|
for i in MouseButton.low.int ..< MouseButton.size:
|
||||||
|
let bit = raw and 0x1
|
||||||
|
if bit == 1:
|
||||||
|
result.incl(MouseButton(BIT(i)))
|
||||||
|
raw = raw shr 1
|
||||||
|
|
||||||
|
proc mouseRead*(): MousePosition =
|
||||||
|
var pos: ptr MousePosition
|
||||||
|
hidMouseRead(pos)
|
||||||
|
result = pos[]
|
||||||
|
|
||||||
|
proc keyboardModifierHeld*(modifier: KeyboardModifier): bool =
|
||||||
|
hidKeyboardModifierHeld(modifier.HidKeyboardModifier)
|
||||||
|
|
||||||
|
proc keyboardModifierDown*(modifier: KeyboardModifier): bool =
|
||||||
|
hidKeyboardModifierDown(modifier.HidKeyboardModifier)
|
||||||
|
|
||||||
|
proc keyboardModifierUp*(modifier: KeyboardModifier): bool =
|
||||||
|
hidKeyboardModifierUp(modifier.HidKeyboardModifier)
|
||||||
|
|
||||||
|
proc keyboardHeld*(key: KeyboardKey): bool =
|
||||||
|
hidKeyboardHeld(key.HidKeyboardScancode)
|
||||||
|
|
||||||
|
proc keyboardDown*(key: KeyboardKey): bool =
|
||||||
|
hidKeyboardDown(key.HidKeyboardScancode)
|
||||||
|
|
||||||
|
proc keyboardUp*(key: KeyboardKey): bool =
|
||||||
|
hidKeyboardUp(key.HidKeyboardScancode)
|
||||||
|
|
||||||
|
proc touchCount*(): uint32 =
|
||||||
|
hidTouchCount()
|
||||||
|
|
||||||
|
proc touchRead*(pointId: uint32): TouchPosition =
|
||||||
|
var touch: ptr TouchPosition
|
||||||
|
hidTouchRead(touch, pointId)
|
||||||
|
result = touch[]
|
||||||
|
|
||||||
|
proc joystickRead*(id: Controller, stick: ControllerJoystick): JoystickPosition =
|
||||||
|
var pos: ptr JoystickPosition
|
||||||
|
hidJoystickRead(pos, id.HidControllerID, stick.HidControllerJoystick)
|
||||||
|
result = pos[]
|
||||||
|
|
||||||
|
## / This can be used to check what CONTROLLER_P1_AUTO uses.
|
||||||
|
## / Returns 0 when CONTROLLER_PLAYER_1 is connected, otherwise returns 1 for
|
||||||
|
## handheld-mode.
|
||||||
|
proc getHandheldMode*(): bool =
|
||||||
|
hidGetHandheldMode()
|
||||||
|
|
||||||
|
## / Use this if you want to use a single joy-con as a dedicated CONTROLLER_PLAYER_*.
|
||||||
|
## / When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1
|
||||||
|
## and CONTROLLER_PLAYER_2 for example).
|
||||||
|
## / id must be CONTROLLER_PLAYER_*.
|
||||||
|
proc setJoyConModeSingle*(id: Controller): Result =
|
||||||
|
if not (id in {Controller.Player1 .. Controller.Player8}):
|
||||||
|
raiseEx(ControllerSelectError, "Must be controller 1-8")
|
||||||
|
hidSetNpadJoyAssignmentModeSingleByDefault(id.HidControllerId).newResult
|
||||||
|
|
||||||
|
## / Use this if you want to use a pair of joy-cons as a single CONTROLLER_PLAYER_*.
|
||||||
|
## Only necessary if you want to use this mode in your application after \ref
|
||||||
|
## hidSetNpadJoyAssignmentModeSingleByDefault was used with this pair of joy-cons.
|
||||||
|
## / Used automatically during app startup/exit for all controllers.
|
||||||
|
## / When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1
|
||||||
|
## and CONTROLLER_PLAYER_2 for example).
|
||||||
|
## / id must be CONTROLLER_PLAYER_*.
|
||||||
|
proc setJoyconModeDual*(id: Controller): Result =
|
||||||
|
if not (id in {Controller.Player1 .. Controller.Player8}):
|
||||||
|
raiseEx(ControllerSelectError, "Must be controller 1-8")
|
||||||
|
hidSetNpadJoyAssignmentModeDual(id.HidControllerId).newResult
|
||||||
|
|
||||||
|
## / Merge two single joy-cons into a dual-mode controller. Use this after \ref
|
||||||
|
## hidSetNpadJoyAssignmentModeDual, when \ref hidSetNpadJoyAssignmentModeSingleByDefault
|
||||||
|
## was previously used (this includes using this manually at application exit).
|
||||||
|
proc mergeSingleJoyAsDualJoy*(id1: Controller; id2: Controller): Result =
|
||||||
|
hidMergeSingleJoyAsDualJoy(id1.HidControllerID, id2.HidControllerId).newResult
|
||||||
|
|
||||||
|
|
||||||
|
proc initializeVibrationDevices*(VibrationDeviceHandles: ptr uint32;
|
||||||
|
total_handles: csize; id: HidControllerID;
|
||||||
|
`type`: HidControllerType): Result =
|
||||||
|
discard
|
||||||
|
|
||||||
|
## / Gets HidVibrationDeviceInfo for the specified VibrationDeviceHandle.
|
||||||
|
proc getVibrationDeviceInfo*(VibrationDeviceHandle: ptr uint32;
|
||||||
|
VibrationDeviceInfo: ptr HidVibrationDeviceInfo): Result =
|
||||||
|
newResult(0)
|
||||||
|
|
||||||
|
## / Send the VibrationValue to the specified VibrationDeviceHandle.
|
||||||
|
proc sendVibrationValue*(VibrationDeviceHandle: ptr uint32;
|
||||||
|
VibrationValue: ptr HidVibrationValue): Result =
|
||||||
|
discard
|
||||||
|
|
||||||
|
## / Gets the current HidVibrationValue for the specified VibrationDeviceHandle.
|
||||||
|
proc getActualVibrationValue*(VibrationDeviceHandle: ptr uint32;
|
||||||
|
VibrationValue: ptr HidVibrationValue): Result =
|
||||||
|
discard
|
||||||
|
|
||||||
|
## / Sets whether vibration is allowed, this also affects the config displayed by
|
||||||
|
## System Settings.
|
||||||
|
proc permitVibration*(flag: bool): Result =
|
||||||
|
discard
|
||||||
|
|
||||||
|
## / Gets whether vibration is allowed.
|
||||||
|
proc isVibrationPermitted*(flag: ptr bool): Result =
|
||||||
|
discard
|
||||||
|
|
||||||
|
## / Send VibrationValues[index] to VibrationDeviceHandles[index], where count is the
|
||||||
|
## number of entries in the VibrationDeviceHandles/VibrationValues arrays.
|
||||||
|
proc sendVibrationValues*(VibrationDeviceHandles: ptr uint32;
|
||||||
|
VibrationValues: ptr HidVibrationValue; count: csize): Result =
|
||||||
|
discard
|
||||||
|
|
@ -109,19 +109,26 @@ proc newResult*(code: uint32): Result =
|
||||||
let resCode = MAKERESULT(moduleCode, descCode)
|
let resCode = MAKERESULT(moduleCode, descCode)
|
||||||
|
|
||||||
var description = ""
|
var description = ""
|
||||||
|
try:
|
||||||
case module
|
case module
|
||||||
of Module.Invalid:
|
of Module.Invalid:
|
||||||
discard
|
discard
|
||||||
of Module.Kernel:
|
of Module.Kernel:
|
||||||
result.kernelError = KernelError(resCode)
|
result.kernelError = KernelError(resCode)
|
||||||
description = $result.kernelError
|
description = $result.kernelError
|
||||||
of Module.Libnx:
|
of Module.Libnx:
|
||||||
result.libnxError = LibnxError(resCode)
|
result.libnxError = LibnxError(resCode)
|
||||||
description = $result.libnxError
|
description = $result.libnxError
|
||||||
of Module.LibnxNvidia:
|
of Module.LibnxNvidia:
|
||||||
result.libnxNvidiaError = LibnxNvidiaError(resCode)
|
result.libnxNvidiaError = LibnxNvidiaError(resCode)
|
||||||
description = $result.libnxNvidiaError
|
description = $result.libnxNvidiaError
|
||||||
|
except:
|
||||||
|
echo "Converting to result failed: " & getCurrentExceptionMsg()
|
||||||
|
echo "Code: " & $code
|
||||||
|
echo "ModuleCode: " & $moduleCode
|
||||||
|
echo "Module: " & $module
|
||||||
|
echo "DescCode: " & $descCode
|
||||||
|
echo "ResultCode: " & $resCode
|
||||||
|
|
||||||
result.module = $module
|
result.module = $module
|
||||||
result.description = description
|
result.description = description
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,84 @@
|
||||||
|
import macros, strutils, math
|
||||||
|
|
||||||
|
proc size*(enumTy: typedesc): int =
|
||||||
|
# Returns the number of items in a bit set enum
|
||||||
|
log2(float64(enumTy.high)).int + 1
|
||||||
|
|
||||||
|
template recursive(node, action: untyped): untyped {.dirty.} =
|
||||||
|
## recursively iterate over AST nodes and perform an
|
||||||
|
## action on them
|
||||||
|
proc helper(child: NimNode): NimNode {.gensym.}=
|
||||||
|
action
|
||||||
|
result = child.copy()
|
||||||
|
for c in child.children:
|
||||||
|
if child.kind == nnkCall and c.kind == nnkDotExpr:
|
||||||
|
# ignore dot expressions that are also calls
|
||||||
|
continue
|
||||||
|
result.add helper(c)
|
||||||
|
discard helper(node)
|
||||||
|
|
||||||
|
macro niceify*(enumType: typed, replaceNameField: string): untyped =
|
||||||
|
##
|
||||||
|
## niceify(HidMouseButton, "Hid:MOUSE_") transforms this:
|
||||||
|
##
|
||||||
|
## HidMouseButton* {.size: sizeof(cint)} = enum
|
||||||
|
## MOUSE_LEFT = BIT(0), MOUSE_RIGHT = BIT(1), MOUSE_MIDDLE = BIT(2),
|
||||||
|
## MOUSE_FORWARD = BIT(3), MOUSE_BACK = BIT(4)
|
||||||
|
##
|
||||||
|
## into this:
|
||||||
|
##
|
||||||
|
## MouseButton {.size: 4, pure.} = enum
|
||||||
|
## Left = MOUSE_LEFT, Right = MOUSE_RIGHT, Middle = MOUSE_MIDDLE,
|
||||||
|
## Forward = MOUSE_FORWARD,
|
||||||
|
## Back = MOUSE_BACK
|
||||||
|
##
|
||||||
|
## If any fields begin with a number, the first letter of the name after
|
||||||
|
## the colon will be used in addition. (128 -> M128 in this case)
|
||||||
|
|
||||||
|
let replaceSplit = replaceNameField.strVal.split(":")
|
||||||
|
var
|
||||||
|
replaceName: string
|
||||||
|
replaceField: string
|
||||||
|
replaceNameWith = ""
|
||||||
|
replaceFieldWith = ""
|
||||||
|
|
||||||
|
if replaceSplit.len == 2:
|
||||||
|
replaceName = replaceSplit[0]
|
||||||
|
replaceField = replaceSplit[1]
|
||||||
|
else:
|
||||||
|
replaceName = replaceSplit[0]
|
||||||
|
replaceNameWith = replaceSplit[1]
|
||||||
|
replaceField = replaceSplit[2]
|
||||||
|
replaceFieldWith = replaceSplit[3]
|
||||||
|
|
||||||
|
var node = enumType.getImpl().copy()
|
||||||
|
recursive(node):
|
||||||
|
if child.kind == nnkPragmaExpr:
|
||||||
|
child[0] = postFix(
|
||||||
|
ident(child[0].strVal.replace($replaceName, replaceNameWith)),
|
||||||
|
"*"
|
||||||
|
)
|
||||||
|
|
||||||
|
if child.kind == nnkPragma:
|
||||||
|
child.add(ident("pure"))
|
||||||
|
|
||||||
|
if child.kind == nnkEnumFieldDef:
|
||||||
|
let
|
||||||
|
lhs = child[0]
|
||||||
|
rhs = child[1]
|
||||||
|
name = lhs.strVal
|
||||||
|
var
|
||||||
|
newName = name.replace($replaceField, replaceFieldWith)
|
||||||
|
.normalize().capitalizeAscii()
|
||||||
|
firstChar = newName[0]
|
||||||
|
|
||||||
|
if firstChar in Digits:
|
||||||
|
newName = replaceField[0] & newName
|
||||||
|
|
||||||
|
child[0] = ident(newName)
|
||||||
|
child[1] = ident(name)
|
||||||
|
|
||||||
|
return newNimNode(nnkTypeSection).add(node)
|
||||||
|
|
||||||
type
|
type
|
||||||
BufferError* = object of Exception
|
BufferError* = object of Exception
|
||||||
|
|
@ -8,6 +88,7 @@ type
|
||||||
len*: int
|
len*: int
|
||||||
data*: ptr UncheckedArray[T]
|
data*: ptr UncheckedArray[T]
|
||||||
|
|
||||||
|
|
||||||
template raiseEx*(ty: untyped, message: string): untyped =
|
template raiseEx*(ty: untyped, message: string): untyped =
|
||||||
raise newException(ty, message)
|
raise newException(ty, message)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue