Compare commits
No commits in common. "master" and "0.1.6" have entirely different histories.
15 changed files with 277 additions and 224 deletions
27
README.md
27
README.md
|
|
@ -1,36 +1,21 @@
|
||||||
# nim-libnx
|
# nim-libnx
|
||||||
Libnx ported to the Nim programming language. You will need a Nim compiler with Nintendo switch support which can be found in the latest devel branch of the Nim compiler.
|
Libnx ported to the Nim programming language. You will need a nim compiler with Nintendo switch support which can be found [here](https://github.com/jyapayne/Nim/tree/nintendo_switch_support) until the PR is accepted.
|
||||||
|
|
||||||
You also must have DevkitPro and switch (libnx) libraries for [Mac and Linux](https://github.com/devkitPro/pacman/releases) or [Windows](https://github.com/devkitPro/installer/releases) installed.
|
You also must have DevkitPro and switch (libnx) libraries for [Mac and Linux](https://github.com/devkitPro/pacman/releases) or [Windows](https://github.com/devkitPro/installer/releases) installed. The DEVKITPRO environment variable must also exist and point to a directory with the following structure:
|
||||||
|
|
||||||
From dkp-pacman, the switch libraries can be installed with:
|
|
||||||
|
|
||||||
```
|
|
||||||
dkp-pacman -Syu
|
|
||||||
dkp-pacman -S switch-dev
|
|
||||||
## When it asks for installation options, choose the default which will install everything
|
|
||||||
```
|
|
||||||
|
|
||||||
The DEVKITPRO environment variable must also exist and point to a directory with the following structure:
|
|
||||||
|
|
||||||
|
- `DEVKITPRO/portlibs/switch/lib`
|
||||||
- `DEVKITPRO/libnx/lib`
|
- `DEVKITPRO/libnx/lib`
|
||||||
|
- `DEVKITPRO/portlibs/switch/include`
|
||||||
- `DEVKITPRO/libnx/include`
|
- `DEVKITPRO/libnx/include`
|
||||||
|
|
||||||
OR you must specify a valid libnx path and/or devkitpro path to the `switch_build` utility:
|
|
||||||
|
|
||||||
```bash
|
##Install
|
||||||
switch_build --libnxPath:"C:\devkitPro\libnx" --author:"Joey" --version:"1.0.0" .\examples\accounts\account_ex.nim
|
|
||||||
# OR
|
|
||||||
switch_build --devkitProPath:"C:\devkitPro" --author:"Joey" --version:"1.0.0" .\examples\accounts\account_ex.nim
|
|
||||||
```
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Simply run
|
Simply run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Because of a bug in nimble right now, you must install this first!
|
# Because of a bug in nimble right now, you must install this first!
|
||||||
nimble install nimgen@#head
|
nimble install "https://github.com/jyapayne/nimgenEx#head"
|
||||||
nimble install
|
nimble install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
4
config.nims
Normal file
4
config.nims
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
switch("passC", "-I" & thisDir() & "/src/libnx/wrapper/nx/include")
|
||||||
|
switch("passL", "-specs="&thisDir()&"/src/libnx/wrapper/nx/switch.specs -L"&thisDir()&"/src/libnx/wrapper/nx/lib -lnx")
|
||||||
|
#switch("passC", "-I$DEVKITPRO/libnx/include")
|
||||||
|
#switch("passL", "-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx")
|
||||||
|
|
@ -2,7 +2,7 @@ import sets, strutils
|
||||||
import libnx/[graphics, console, account, input, app]
|
import libnx/[graphics, console, account, input, app]
|
||||||
import libnx/ext/integer128
|
import libnx/ext/integer128
|
||||||
|
|
||||||
mainFunction:
|
proc main() =
|
||||||
graphics.initDefault()
|
graphics.initDefault()
|
||||||
console.init()
|
console.init()
|
||||||
|
|
||||||
|
|
@ -43,3 +43,5 @@ mainFunction:
|
||||||
|
|
||||||
if ControllerKey.Plus in keysDown:
|
if ControllerKey.Plus in keysDown:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import sets
|
||||||
import libnx/[graphics, console, app, input]
|
import libnx/[graphics, console, app, input]
|
||||||
|
|
||||||
|
|
||||||
mainFunction:
|
proc main() =
|
||||||
initDefault()
|
initDefault()
|
||||||
console.init()
|
console.init()
|
||||||
|
|
||||||
|
|
@ -15,3 +15,5 @@ mainFunction:
|
||||||
|
|
||||||
if ControllerKey.Plus in keysDown:
|
if ControllerKey.Plus in keysDown:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
|
||||||
28
libnx.nimble
28
libnx.nimble
|
|
@ -1,39 +1,23 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.2.2"
|
version = "0.1.6"
|
||||||
author = "Joey Payne"
|
author = "Joey Payne"
|
||||||
description = "Nintendo Switch library libnx for Nim."
|
description = "Nintendo Switch library libnx for Nim."
|
||||||
license = "The Unlicense"
|
license = "The Unlicense"
|
||||||
|
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
|
|
||||||
import distros
|
|
||||||
|
|
||||||
var prefix = ""
|
|
||||||
var username = getEnv("USER")
|
|
||||||
if detectOs(Windows):
|
|
||||||
prefix = "cmd /c "
|
|
||||||
username = getEnv("USERNAME")
|
|
||||||
|
|
||||||
# Deps
|
# Deps
|
||||||
requires "nim >= 0.18.1", "nimgen#dc9943a22c9c8f6a5a6a92f0055e1de4dfaf87d2"
|
requires "nim >= 0.18.1", "https://github.com/genotrance/nimgen#head"
|
||||||
requires "switch_build >= 0.1.3"
|
requires "https://github.com/jyapayne/switch-build#head"
|
||||||
|
|
||||||
task setup, "Download and generate bindings":
|
task setup, "Download and generate bindings":
|
||||||
echo "Building libnx..."
|
echo "Building libnx..."
|
||||||
exec prefix & "nimgen libnxGen.cfg"
|
exec "nimgen libnxGen.cfg"
|
||||||
|
|
||||||
task buildExamples, "Build switch examples":
|
task buildExamples, "Build switch examples":
|
||||||
if detectOs(Windows):
|
exec "switch_build --libnxPath='" & thisDir() & "/src/libnx/wrapper/nx/' --author='jyapayne' --version='1.0.0' examples/helloworld/helloworld.nim"
|
||||||
let devkitPath = getEnv("DEVKITPRO")
|
exec "switch_build --libnxPath='" & thisDir() & "/src/libnx/wrapper/nx/' --author='jyapayne' --version='1.0.0' examples/accounts/account_ex.nim"
|
||||||
if devkitPath == "" or not dirExists(devkitPath):
|
|
||||||
echo "You must set the DEVKITPRO environment variable to something valid!"
|
|
||||||
else:
|
|
||||||
exec prefix & "switch_build --libnxPath=\"" & devkitPath & "/libnx/\" --author=\"" & username & "\" --version=\"1.0.0\" examples/helloworld/helloworld.nim"
|
|
||||||
exec prefix & "switch_build --libnxPath=\"" & devkitPath & "/libnx/\" --author=\"" & username & "\" --version=\"1.0.0\" examples/accounts/account_ex.nim"
|
|
||||||
else:
|
|
||||||
exec prefix & "switch_build --libnxPath=\"" & thisDir() & "/src/libnx/wrapper/nx/\" --author=\"" & username & "\" --version=\"1.0.0\" examples/helloworld/helloworld.nim"
|
|
||||||
exec prefix & "switch_build --libnxPath=\"" & thisDir() & "/src/libnx/wrapper/nx/\" --author=\"" & username & "\" --version=\"1.0.0\" examples/accounts/account_ex.nim"
|
|
||||||
|
|
||||||
before install:
|
before install:
|
||||||
setupTask()
|
setupTask()
|
||||||
|
|
|
||||||
132
libnxGen.cfg
132
libnxGen.cfg
|
|
@ -8,63 +8,26 @@ filter=lock
|
||||||
"${output}/nx/include"
|
"${output}/nx/include"
|
||||||
"${output}/nx/include/switch"
|
"${output}/nx/include/switch"
|
||||||
"${output}/nx/include/switch/arm"
|
"${output}/nx/include/switch/arm"
|
||||||
"${output}/nx/include/switch/audio"
|
|
||||||
"${output}/nx/include/switch/display"
|
|
||||||
"${output}/nx/include/switch/kernel"
|
"${output}/nx/include/switch/kernel"
|
||||||
"${output}/nx/include/switch/nvidia"
|
"${output}/nx/include/switch/services"
|
||||||
|
"${output}/nx/include/switch/audio"
|
||||||
|
"${output}/nx/include/switch/gfx"
|
||||||
"${output}/nx/include/switch/runtime"
|
"${output}/nx/include/switch/runtime"
|
||||||
"${output}/nx/include/switch/runtime/util"
|
"${output}/nx/include/switch/runtime/util"
|
||||||
"${output}/nx/include/switch/runtime/devices"
|
"${output}/nx/include/switch/runtime/devices"
|
||||||
"${output}/nx/include/switch/services"
|
|
||||||
"${DEVKITPRO}/devkitA64/aarch64-none-elf/include/"
|
"${DEVKITPRO}/devkitA64/aarch64-none-elf/include/"
|
||||||
|
"${DEVKITA64}/aarch64-none-elf/include/"
|
||||||
|
|
||||||
[n.exclude]
|
[n.exclude]
|
||||||
"${output}/nim.cfg"
|
"${output}/nim.cfg"
|
||||||
"${output}/config.nims"
|
"${output}/config.nims"
|
||||||
|
|
||||||
[svc.h]
|
|
||||||
search = "PACKED"
|
|
||||||
replace = ""
|
|
||||||
|
|
||||||
search.noreturn = "NORETURN"
|
|
||||||
replace.noreturn = ""
|
|
||||||
|
|
||||||
defines=true
|
|
||||||
|
|
||||||
[result.h]
|
|
||||||
defines = true
|
|
||||||
|
|
||||||
[thread_context.h]
|
|
||||||
preprocess = false
|
|
||||||
|
|
||||||
[hid.h]
|
|
||||||
defines = true
|
|
||||||
search.static_assert = "static_assert"
|
|
||||||
replace.static_assert = "// static_assert"
|
|
||||||
search.touch = "touchPosition"
|
|
||||||
replace.touch = "TouchPosition"
|
|
||||||
|
|
||||||
[ipc.h]
|
|
||||||
defines = true
|
|
||||||
|
|
||||||
[romfs_dev.h]
|
|
||||||
search = "romfs_"
|
|
||||||
replace = "Romfs_"
|
|
||||||
|
|
||||||
[gfx.h]
|
|
||||||
defines = true
|
|
||||||
|
|
||||||
[ioctl.h]
|
|
||||||
defines = true
|
|
||||||
search = "_NV_"
|
|
||||||
replace = "UNV_"
|
|
||||||
|
|
||||||
search.nv = "__nv_"
|
|
||||||
replace.nv = "DUnv_"
|
|
||||||
|
|
||||||
[n.wildcard]
|
[n.wildcard]
|
||||||
wildcard.1 = "console.h"
|
wildcard.1 = "console.h"
|
||||||
rename = "$replace(console=cons)"
|
rename = "$replace(console=con)"
|
||||||
|
|
||||||
|
search = "_Bool"
|
||||||
|
replace = "bool"
|
||||||
|
|
||||||
wildcard.2 = "*.h"
|
wildcard.2 = "*.h"
|
||||||
|
|
||||||
|
|
@ -105,8 +68,10 @@ replace.cdecl = "cdecl"
|
||||||
|
|
||||||
[n.prepare]
|
[n.prepare]
|
||||||
git = "https://github.com/switchbrew/libnx"
|
git = "https://github.com/switchbrew/libnx"
|
||||||
execute-lin = """cd ${output}; make;"""
|
execute = """
|
||||||
execute-mac = """cd ${output}; make;"""
|
cd ${output}
|
||||||
|
make
|
||||||
|
"""
|
||||||
|
|
||||||
[n.post]
|
[n.post]
|
||||||
reset=true
|
reset=true
|
||||||
|
|
@ -116,21 +81,56 @@ create = """
|
||||||
--path:"../"
|
--path:"../"
|
||||||
--path:"../../"
|
--path:"../../"
|
||||||
"""
|
"""
|
||||||
noprocess=true
|
|
||||||
|
|
||||||
[src/libnx/wrapper/config.nims]
|
[src/libnx/wrapper/config.nims]
|
||||||
create = """
|
create = """
|
||||||
switch("passC", "-I" & thisDir() & "/nx/include")
|
switch("passC", "-I" & thisDir() & "/nx/include")
|
||||||
switch("passL", "-specs=" & thisDir() & "/nx/switch.specs -L" & thisDir() & "/nx/lib -lnx")
|
switch("passL", "-specs=" & thisDir() & "/nx/switch.specs -L" & thisDir() & "/nx/lib -lnx")
|
||||||
"""
|
"""
|
||||||
noprocess=true
|
|
||||||
|
[result.h]
|
||||||
|
defines = true
|
||||||
|
|
||||||
|
[hid.h]
|
||||||
|
defines = true
|
||||||
|
search.static_assert = "static_assert"
|
||||||
|
replace.static_assert = "// static_assert"
|
||||||
|
search.touch = "touchPosition"
|
||||||
|
replace.touch = "TouchPosition"
|
||||||
|
|
||||||
|
[ipc.h]
|
||||||
|
defines = true
|
||||||
|
|
||||||
|
[romfs_dev.h]
|
||||||
|
search = "romfs_"
|
||||||
|
replace = "Romfs_"
|
||||||
|
|
||||||
|
[gfx.h]
|
||||||
|
defines = true
|
||||||
|
|
||||||
|
[ioctl.h]
|
||||||
|
defines = true
|
||||||
|
search = "_NV_"
|
||||||
|
replace = "UNV_"
|
||||||
|
|
||||||
|
search.nv = "__nv_"
|
||||||
|
replace.nv = "DUnv_"
|
||||||
|
|
||||||
|
[svc.h]
|
||||||
|
search = "PACKED"
|
||||||
|
replace = ""
|
||||||
|
|
||||||
|
search.noreturn = "NORETURN"
|
||||||
|
replace.noreturn = ""
|
||||||
|
|
||||||
|
defines=true
|
||||||
|
pipe = "vim -es +'g/^static inline.*{/norm f{d%r;' -es +%print -es +q! $file"
|
||||||
|
|
||||||
[switch.h]
|
[switch.h]
|
||||||
preprocess = true
|
preprocess = true
|
||||||
defines = true
|
defines = true
|
||||||
recurse = true
|
recurse = true
|
||||||
|
|
||||||
|
|
||||||
[types.nim]
|
[types.nim]
|
||||||
search.o = " uint8*"
|
search.o = " uint8*"
|
||||||
prepend.o = """
|
prepend.o = """
|
||||||
|
|
@ -169,26 +169,6 @@ import libnx/ext/integer128
|
||||||
template BIT*(n): auto = (1.uint shl n)
|
template BIT*(n): auto = (1.uint shl n)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[thread_context.nim]
|
|
||||||
search.timport = "../types"
|
|
||||||
replace.timport = "libnx/wrapper/types"
|
|
||||||
|
|
||||||
prepend.o = """
|
|
||||||
import libnx/ext/integer128
|
|
||||||
"""
|
|
||||||
|
|
||||||
search.cpuall = "RegisterGroup_CpuAll ="
|
|
||||||
comment.cpuall = 1
|
|
||||||
|
|
||||||
search.fpugprs = "RegisterGroup_FpuGprs ="
|
|
||||||
prepend.fpugprs = "RegisterGroup_CpuAll = BIT(0) or BIT(1), ## /< All CPU registers."
|
|
||||||
|
|
||||||
search.fpuall = "RegisterGroup_FpuGprs or RegisterGroup_FpuSprs"
|
|
||||||
replace.fpuall = "BIT(2) or BIT(3)"
|
|
||||||
|
|
||||||
search.groupall = "RegisterGroup_CpuAll or RegisterGroup_FpuAll"
|
|
||||||
replace.groupall = "BIT(0) or BIT(1) or BIT(2) or BIT(3)"
|
|
||||||
|
|
||||||
[svc.nim]
|
[svc.nim]
|
||||||
search.timport = "../types"
|
search.timport = "../types"
|
||||||
replace.timport = "libnx/wrapper/types"
|
replace.timport = "libnx/wrapper/types"
|
||||||
|
|
@ -333,12 +313,7 @@ prepend.o = """
|
||||||
import libnx/ext/integer128
|
import libnx/ext/integer128
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[fence.nim]
|
[con.nim]
|
||||||
prepend.o = """
|
|
||||||
import libnx/wrapper/types
|
|
||||||
"""
|
|
||||||
|
|
||||||
[cons.nim]
|
|
||||||
search.o = "type\n"
|
search.o = "type\n"
|
||||||
prepend.o = """
|
prepend.o = """
|
||||||
|
|
||||||
|
|
@ -374,16 +349,11 @@ replace.threedmoo = "debugDevice_3DMOO*"
|
||||||
search.timport = "../types"
|
search.timport = "../types"
|
||||||
replace.timport = "libnx/wrapper/types"
|
replace.timport = "libnx/wrapper/types"
|
||||||
|
|
||||||
search.fimport = "../nvidia/fence"
|
|
||||||
replace.fimport = "libnx/wrapper/fence"
|
|
||||||
|
|
||||||
[romfs_dev.nim]
|
[romfs_dev.nim]
|
||||||
search.timport = "../types"
|
search.timport = "../types"
|
||||||
replace.timport = "libnx/wrapper/types"
|
replace.timport = "libnx/wrapper/types"
|
||||||
search.servimport = "../services/"
|
search.servimport = "../services/"
|
||||||
replace.servimport = "libnx/wrapper/"
|
replace.servimport = "libnx/wrapper/"
|
||||||
search.o = "../libnx"
|
|
||||||
replace.o = "libnx"
|
|
||||||
|
|
||||||
[n.sourcefile]
|
[n.sourcefile]
|
||||||
"${output}/*.nim"
|
"${output}/*.nim"
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ proc init() =
|
||||||
if code.failed:
|
if code.failed:
|
||||||
raiseEx(
|
raiseEx(
|
||||||
AccountInitError,
|
AccountInitError,
|
||||||
"Error, account api could not be initialized", code
|
"Error, account api could not be initialized: " & code.description
|
||||||
)
|
)
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ proc getImageSize*(profile: AccountProfile): int =
|
||||||
result = 0
|
result = 0
|
||||||
let code = accountProfileGetImageSize(profile.unsafeAddr, res.addr).newResult
|
let code = accountProfileGetImageSize(profile.unsafeAddr, res.addr).newResult
|
||||||
if code.failed:
|
if code.failed:
|
||||||
raiseEx(AccountImageSizeError, "Error, could not get image size", code)
|
raiseEx(AccountImageSizeError, "Error, could not get image size: " & code.description)
|
||||||
result = res.int
|
result = res.int
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ proc imageSize*(user: User): int =
|
||||||
let res = accountProfileGetImageSize(prof.addr, size.addr).newResult
|
let res = accountProfileGetImageSize(prof.addr, size.addr).newResult
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(AccountImageSizeError, "Error, could not get image size", res)
|
raiseEx(AccountImageSizeError, "Error, could not get image size: " & res.description)
|
||||||
|
|
||||||
result = size.int
|
result = size.int
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@ proc getProfileHelper(userID: u128): AccountProfile =
|
||||||
let res = accountGetProfile(result.addr, userID).newResult
|
let res = accountGetProfile(result.addr, userID).newResult
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(AccountUserProfileError, "Error, could not get user profile", res)
|
raiseEx(AccountUserProfileError, "Error, could not get user profile: " & res.description)
|
||||||
|
|
||||||
|
|
||||||
proc loadImage*(user: User): AccountImage =
|
proc loadImage*(user: User): AccountImage =
|
||||||
|
|
@ -128,7 +128,7 @@ proc loadImage*(user: User): AccountImage =
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
prof.close()
|
prof.close()
|
||||||
raiseEx(AccountImageLoadError, "Error, could not load image", res)
|
raiseEx(AccountImageLoadError, "Error, could not load image: " & res.description)
|
||||||
|
|
||||||
prof.close()
|
prof.close()
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ proc getUser*(userID: u128): User =
|
||||||
let res = accountProfileGet(prof.addr, userData.addr, profBase.addr).newResult
|
let res = accountProfileGet(prof.addr, userData.addr, profBase.addr).newResult
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(AccountUserDataError, "Error, could not get user data", res)
|
raiseEx(AccountUserDataError, "Error, could not get user data: " & res.description)
|
||||||
|
|
||||||
result.username = profBase.username.join("")
|
result.username = profBase.username.join("")
|
||||||
result.lastEdited = profBase.lastEditTimestamp
|
result.lastEdited = profBase.lastEditTimestamp
|
||||||
|
|
@ -173,7 +173,7 @@ proc getActiveUser*(): User =
|
||||||
var res = accountGetActiveUser(userID.addr, selected.addr).newResult
|
var res = accountGetActiveUser(userID.addr, selected.addr).newResult
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(AccountActiveUserError, "Error, could not get active user ID", res)
|
raiseEx(AccountActiveUserError, "Error, could not get active user ID: " & res.description)
|
||||||
|
|
||||||
if not selected:
|
if not selected:
|
||||||
raiseEx(AccountUserNotSelectedError, "No user currently selected!")
|
raiseEx(AccountUserNotSelectedError, "No user currently selected!")
|
||||||
|
|
@ -189,7 +189,7 @@ proc getActiveUser*(): User =
|
||||||
res = accountProfileGet(prof.addr, userData.addr, profBase.addr).newResult
|
res = accountProfileGet(prof.addr, userData.addr, profBase.addr).newResult
|
||||||
|
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(AccountUserDataError, "Error, could not get user data", res)
|
raiseEx(AccountUserDataError, "Error, could not get user data: " & res.description)
|
||||||
|
|
||||||
result.username = profBase.username.join("")
|
result.username = profBase.username.join("")
|
||||||
result.lastEdited = profBase.lastEditTimestamp
|
result.lastEdited = profBase.lastEditTimestamp
|
||||||
|
|
@ -209,7 +209,7 @@ proc getProfile*(user: User): Profile =
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(
|
raiseEx(
|
||||||
AccountUserProfileError,
|
AccountUserProfileError,
|
||||||
"Error, could not get account profile", res
|
"Error, could not get account profile: " & res.description
|
||||||
)
|
)
|
||||||
|
|
||||||
result.service = newService(prof.s)
|
result.service = newService(prof.s)
|
||||||
|
|
@ -224,7 +224,7 @@ proc getUserCount*(): int32 =
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(
|
raiseEx(
|
||||||
AccountUserCountError,
|
AccountUserCountError,
|
||||||
"Error, could not get user count", res
|
"Error, could not get user count: " & res.description
|
||||||
)
|
)
|
||||||
result = count
|
result = count
|
||||||
|
|
||||||
|
|
@ -247,7 +247,7 @@ proc listAllUsers*(): seq[User] =
|
||||||
if res.failed:
|
if res.failed:
|
||||||
raiseEx(
|
raiseEx(
|
||||||
AccountUserListError,
|
AccountUserListError,
|
||||||
"Error, could not list users", res
|
"Error, could not list users: " & res.description
|
||||||
)
|
)
|
||||||
|
|
||||||
for i in 0 ..< usersReturned.int:
|
for i in 0 ..< usersReturned.int:
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,8 @@
|
||||||
import libnx/graphics, libnx/input, libnx/wrapper/applet
|
import libnx/graphics, libnx/wrapper/hid, libnx/wrapper/applet
|
||||||
|
|
||||||
template mainFunction*(code: untyped): untyped =
|
|
||||||
proc main() =
|
|
||||||
try:
|
|
||||||
code
|
|
||||||
except:
|
|
||||||
let e = getCurrentException()
|
|
||||||
echo ""
|
|
||||||
echo e.getStackTrace()
|
|
||||||
echo getCurrentExceptionMsg()
|
|
||||||
echo ""
|
|
||||||
echo "Your program has crashed. Press + on Controller 1 to exit safely."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
while appletMainLoop():
|
|
||||||
scanInput()
|
|
||||||
|
|
||||||
let keysDown = keysDown(Controller.P1_AUTO)
|
|
||||||
|
|
||||||
if ControllerKey.Plus in keysDown:
|
|
||||||
break
|
|
||||||
|
|
||||||
flushBuffers()
|
|
||||||
swapBuffers()
|
|
||||||
waitForVSync()
|
|
||||||
try:
|
|
||||||
graphics.exit()
|
|
||||||
quit(0)
|
|
||||||
except:
|
|
||||||
quit(0)
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
template mainLoop*(code: untyped): untyped =
|
template mainLoop*(code: untyped): untyped =
|
||||||
while appletMainLoop():
|
while appletMainLoop():
|
||||||
scanInput()
|
hidScanInput()
|
||||||
|
|
||||||
code
|
code
|
||||||
|
|
||||||
|
|
|
||||||
4
src/libnx/config.nims
Normal file
4
src/libnx/config.nims
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
switch("passC", "-I" & thisDir() & "/wrapper/nx/include")
|
||||||
|
switch("passL", "-specs=" & thisDir() & "/wrapper/nx/switch.specs -L" & thisDir() & "/wrapper/nx/lib -lnx")
|
||||||
|
#switch("passC", "-I$DEVKITPRO/libnx/include")
|
||||||
|
#switch("passL", "-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx")
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import macros, strutils, sets
|
import libnx/wrapper/con
|
||||||
import libnx/wrapper/cons
|
|
||||||
import libnx/utils
|
import libnx/utils
|
||||||
|
import macros, strutils
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -37,19 +37,18 @@ type
|
||||||
tabSize*: int
|
tabSize*: int
|
||||||
fg*: int
|
fg*: int
|
||||||
bg*: int
|
bg*: int
|
||||||
flags*: HashSet[Style]
|
flags*: set[Style]
|
||||||
printCharCallback*: PrintCallback
|
printCharCallback*: PrintCallback
|
||||||
initialised*: bool
|
initialised*: bool
|
||||||
|
|
||||||
DebugDevice* {.size: sizeof(cint), pure.} = enum
|
DebugDevice* {.size: sizeof(cint), pure.} = enum
|
||||||
Null, Service, Console, ThreeDMOO
|
Null, Service, Console, ThreeDMOO
|
||||||
|
|
||||||
var currentConsole {.threadvar.}: Console
|
|
||||||
|
|
||||||
proc toConsole(pconsole: ptr PrintConsole): Console =
|
proc toConsole(pconsole: ptr PrintConsole): Console =
|
||||||
result = new(Console)
|
result = new(Console)
|
||||||
result.pcon = pconsole
|
result.pcon = pconsole
|
||||||
result.font = pconsole.font
|
result.font = pconsole.font
|
||||||
|
result.cursorX = pconsole.cursorX
|
||||||
result.frameBuffer = cast[ptr UncheckedArray[uint32]](pconsole.frameBuffer)
|
result.frameBuffer = cast[ptr UncheckedArray[uint32]](pconsole.frameBuffer)
|
||||||
result.frameBuffer2 = cast[ptr UncheckedArray[uint32]](pconsole.frameBuffer2)
|
result.frameBuffer2 = cast[ptr UncheckedArray[uint32]](pconsole.frameBuffer2)
|
||||||
result.cursorX = pconsole.cursorX
|
result.cursorX = pconsole.cursorX
|
||||||
|
|
@ -65,7 +64,7 @@ proc toConsole(pconsole: ptr PrintConsole): Console =
|
||||||
result.tabSize = pconsole.tabSize
|
result.tabSize = pconsole.tabSize
|
||||||
result.fg = pconsole.fg
|
result.fg = pconsole.fg
|
||||||
result.bg = pconsole.bg
|
result.bg = pconsole.bg
|
||||||
result.flags = initSet[Style]()
|
result.flags = {}
|
||||||
|
|
||||||
result.pcon.PrintChar = proc (con: pointer, c: cint): bool {.cdecl.} =
|
result.pcon.PrintChar = proc (con: pointer, c: cint): bool {.cdecl.} =
|
||||||
let console = cast[ptr PrintConsole](con).toConsole()
|
let console = cast[ptr PrintConsole](con).toConsole()
|
||||||
|
|
@ -87,21 +86,20 @@ proc setWindow*(console: Console, x, y, width, height: int) =
|
||||||
console.windowY = console.pcon.windowY.int
|
console.windowY = console.pcon.windowY.int
|
||||||
|
|
||||||
proc getDefault*(): Console =
|
proc getDefault*(): Console =
|
||||||
## Gets the default console with default values
|
|
||||||
let pcon = consoleGetDefault()
|
let pcon = consoleGetDefault()
|
||||||
result = pcon.toConsole()
|
result = pcon.toConsole()
|
||||||
|
|
||||||
proc select*(console: Console): Console =
|
proc select*(console: Console): Console =
|
||||||
currentConsole = consoleInit(console.pcon).toConsole()
|
consoleSelect(console.pcon).toConsole()
|
||||||
return currentConsole
|
|
||||||
|
|
||||||
proc init*(console: Console): Console {.discardable.} =
|
proc init*(console: Console = nil): Console {.discardable.} =
|
||||||
currentConsole = consoleInit(console.pcon).toConsole()
|
var newCon = console
|
||||||
return currentConsole
|
if newCon.isNil:
|
||||||
|
newCon = new(Console)
|
||||||
|
|
||||||
proc init*(): Console {.discardable.} =
|
let pcon = consoleInit(newCon.pcon)
|
||||||
currentConsole = consoleInit(nil).toConsole()
|
newCon = pcon.toConsole()
|
||||||
return currentConsole
|
return newCon
|
||||||
|
|
||||||
proc debugInit*(device: DebugDevice) =
|
proc debugInit*(device: DebugDevice) =
|
||||||
if device == ThreeDMOO:
|
if device == ThreeDMOO:
|
||||||
|
|
@ -112,17 +110,17 @@ proc debugInit*(device: DebugDevice) =
|
||||||
proc clear*() =
|
proc clear*() =
|
||||||
consoleClear()
|
consoleClear()
|
||||||
|
|
||||||
|
var printPos: tuple[row: int, col: int] = (0, 0)
|
||||||
|
|
||||||
|
proc setPrintPos*(pos: tuple[row: int, col: int]) =
|
||||||
|
printPos = pos
|
||||||
|
|
||||||
proc printAt*(pos: tuple[row: int, col: int], args: varargs[string, `$`]) =
|
proc printAt*(pos: tuple[row: int, col: int], args: varargs[string, `$`]) =
|
||||||
echo CONSOLE_ESC("2K"), (CONSOLE_ESC("$#;$#H") % [$pos.row, $pos.col]), args.join("")
|
setPrintPos(pos)
|
||||||
currentConsole.pcon.cursorX = pos.col.int32
|
echo ("\x1b[$#;$#H" % [$pos[0], $pos[1]]), args.join("")
|
||||||
currentConsole.pcon.cursorY = pos.row.int32
|
|
||||||
currentConsole.cursorX = pos.col
|
|
||||||
currentConsole.cursorY = pos.row
|
|
||||||
|
|
||||||
proc print*(args: varargs[string, `$`]) =
|
proc print*(args: varargs[string, `$`]) =
|
||||||
## Will print at the previously set printPos using ``printAt``
|
## Will print at the previously set printPos using ``printAt`` or ``setPrintPos``
|
||||||
## and then increment the row by one
|
## and then increment the row by one
|
||||||
let
|
|
||||||
pcon = currentConsole.pcon
|
|
||||||
printPos = (pcon.cursorY.int+1, pcon.cursorX.int)
|
|
||||||
printAt printPos, args
|
printAt printPos, args
|
||||||
|
printPos.row += 1
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,10 @@ import strutils
|
||||||
import
|
import
|
||||||
libnx/wrapper/types,
|
libnx/wrapper/types,
|
||||||
libnx/wrapper/gfx,
|
libnx/wrapper/gfx,
|
||||||
libnx/results,
|
|
||||||
libnx/utils
|
libnx/utils
|
||||||
|
|
||||||
type
|
type
|
||||||
GraphicsError* = object of Exception
|
GraphicsError* = object of Exception
|
||||||
GraphicsInitError* = object of GraphicsError
|
|
||||||
InitResolutionError* = object of GraphicsError
|
InitResolutionError* = object of GraphicsError
|
||||||
CropBoundsError* = object of GraphicsError
|
CropBoundsError* = object of GraphicsError
|
||||||
|
|
||||||
|
|
@ -55,12 +53,7 @@ var enabled = false
|
||||||
##
|
##
|
||||||
proc initDefault*() =
|
proc initDefault*() =
|
||||||
if not enabled:
|
if not enabled:
|
||||||
let code = gfxInitDefault().newResult
|
gfxInitDefault()
|
||||||
if code.failed:
|
|
||||||
raiseEx(
|
|
||||||
GraphicsInitError,
|
|
||||||
"Error, graphics could not be initialized", code
|
|
||||||
)
|
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
## *
|
## *
|
||||||
|
|
@ -191,6 +184,10 @@ proc getFramebuffer*(): Framebuffer =
|
||||||
## / Sets the \ref GfxMode.
|
## / Sets the \ref GfxMode.
|
||||||
proc setMode*(mode: GfxMode) = gfxSetMode(gfx.GfxMode(mode))
|
proc setMode*(mode: GfxMode) = gfxSetMode(gfx.GfxMode(mode))
|
||||||
|
|
||||||
|
## / Controls whether a vertical-flip is done when determining the pixel-offset within
|
||||||
|
## the actual framebuffer. By default this is enabled.
|
||||||
|
proc setDrawFlip*(enabled: bool) = gfxSetDrawFlip(enabled)
|
||||||
|
|
||||||
## / Configures transform. See the NATIVE_WINDOW_TRANSFORM_* enums in buffer_producer.h.
|
## / Configures transform. See the NATIVE_WINDOW_TRANSFORM_* enums in buffer_producer.h.
|
||||||
## The default is NATIVE_WINDOW_TRANSFORM_FLIP_V.
|
## The default is NATIVE_WINDOW_TRANSFORM_FLIP_V.
|
||||||
proc configureTransform*(transform: BufferTransform) =
|
proc configureTransform*(transform: BufferTransform) =
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,136 @@ type
|
||||||
VibrationInitError* = object of InputError
|
VibrationInitError* = object of InputError
|
||||||
ControllerMergeError* = object of InputError
|
ControllerMergeError* = object of InputError
|
||||||
|
|
||||||
|
####################### Shared memory data ################################
|
||||||
|
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]
|
||||||
|
|
||||||
|
####################### END Shared memory data ################################
|
||||||
|
|
||||||
VibrationDeviceInfo* = HidVibrationDeviceInfo
|
VibrationDeviceInfo* = HidVibrationDeviceInfo
|
||||||
|
|
||||||
VibrationValue* = HidVibrationValue
|
VibrationValue* = HidVibrationValue
|
||||||
|
|
@ -35,6 +165,7 @@ type
|
||||||
JoyconMode {.pure.} = enum
|
JoyconMode {.pure.} = enum
|
||||||
Single, Dual
|
Single, Dual
|
||||||
|
|
||||||
|
|
||||||
proc init*(): Result = hidInitialize().newResult
|
proc init*(): Result = hidInitialize().newResult
|
||||||
proc exit*() = hidExit()
|
proc exit*() = hidExit()
|
||||||
proc reset*() = hidReset()
|
proc reset*() = hidReset()
|
||||||
|
|
@ -290,7 +421,7 @@ proc initializeVibrationDevices*(
|
||||||
if rc.failed:
|
if rc.failed:
|
||||||
raiseEx(
|
raiseEx(
|
||||||
VibrationInitError,
|
VibrationInitError,
|
||||||
"Could not init vibration for controller $# with type $#" %
|
"Could not init vibration for controller #$ with type #$" %
|
||||||
[$controller, $ctype]
|
[$controller, $ctype]
|
||||||
)
|
)
|
||||||
for i in 0 ..< numDevices:
|
for i in 0 ..< numDevices:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import strutils
|
|
||||||
import
|
import
|
||||||
libnx/wrapper/result,
|
libnx/wrapper/result,
|
||||||
libnx/wrapper/types
|
libnx/wrapper/types
|
||||||
|
|
@ -6,7 +5,7 @@ import
|
||||||
type
|
type
|
||||||
|
|
||||||
Module {.pure.} = enum
|
Module {.pure.} = enum
|
||||||
Success = 0,
|
Invalid = 0, # This is just so the nim compiler is happy
|
||||||
Kernel = 1,
|
Kernel = 1,
|
||||||
Libnx = 345,
|
Libnx = 345,
|
||||||
LibnxNvidia = 348
|
LibnxNvidia = 348
|
||||||
|
|
@ -14,8 +13,16 @@ type
|
||||||
Result* = ref object
|
Result* = ref object
|
||||||
code*: uint32
|
code*: uint32
|
||||||
module*: string
|
module*: string
|
||||||
kind*: Module
|
description*: string
|
||||||
error*: string
|
case kind*: Module
|
||||||
|
of Module.Kernel:
|
||||||
|
kernelError*: KernelError
|
||||||
|
of Module.Libnx:
|
||||||
|
libnxError*: LibnxError
|
||||||
|
of Module.LibnxNvidia:
|
||||||
|
libnxNvidiaError*: LibnxNvidiaError
|
||||||
|
else:
|
||||||
|
discard
|
||||||
|
|
||||||
KernelError* {.pure.} = enum
|
KernelError* {.pure.} = enum
|
||||||
Timeout = 117
|
Timeout = 117
|
||||||
|
|
@ -91,6 +98,8 @@ proc newResult*(code: uint32): Result =
|
||||||
result = new(Result)
|
result = new(Result)
|
||||||
|
|
||||||
result.code = code
|
result.code = code
|
||||||
|
if code.R_SUCCEEDED:
|
||||||
|
return
|
||||||
|
|
||||||
let moduleCode = code.R_MODULE
|
let moduleCode = code.R_MODULE
|
||||||
let module = Module(moduleCode)
|
let module = Module(moduleCode)
|
||||||
|
|
@ -99,18 +108,20 @@ proc newResult*(code: uint32): Result =
|
||||||
|
|
||||||
let descCode = code.R_DESCRIPTION
|
let descCode = code.R_DESCRIPTION
|
||||||
|
|
||||||
var error = "Unknown error: module: $# description: $#" %
|
var description = ""
|
||||||
[$moduleCode, $descCode]
|
|
||||||
try:
|
try:
|
||||||
case module
|
case module
|
||||||
of Module.Success:
|
of Module.Invalid:
|
||||||
return
|
discard
|
||||||
of Module.Kernel:
|
of Module.Kernel:
|
||||||
error = $KernelError(descCode)
|
result.kernelError = KernelError(descCode)
|
||||||
|
description = $result.kernelError
|
||||||
of Module.Libnx:
|
of Module.Libnx:
|
||||||
error = $LibnxError(descCode)
|
result.libnxError = LibnxError(descCode)
|
||||||
|
description = $result.libnxError
|
||||||
of Module.LibnxNvidia:
|
of Module.LibnxNvidia:
|
||||||
error = $LibnxNvidiaError(descCode)
|
result.libnxNvidiaError = LibnxNvidiaError(descCode)
|
||||||
|
description = $result.libnxNvidiaError
|
||||||
except:
|
except:
|
||||||
echo "Converting to result failed: " & getCurrentExceptionMsg()
|
echo "Converting to result failed: " & getCurrentExceptionMsg()
|
||||||
echo "Code: " & $code
|
echo "Code: " & $code
|
||||||
|
|
@ -119,4 +130,4 @@ proc newResult*(code: uint32): Result =
|
||||||
echo "DescCode: " & $descCode
|
echo "DescCode: " & $descCode
|
||||||
|
|
||||||
result.module = $module
|
result.module = $module
|
||||||
result.error = error
|
result.description = description
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
import macros, strutils, math, hashes
|
import macros, strutils, math
|
||||||
import libnx/results
|
import libnx/results
|
||||||
|
|
||||||
|
|
||||||
proc hash*(obj: SomeOrdinal): Hash =
|
|
||||||
## Allow hashing of enums with holes
|
|
||||||
result = cast[int](obj)
|
|
||||||
|
|
||||||
proc size*(enumTy: typedesc): int =
|
proc size*(enumTy: typedesc): int =
|
||||||
# Returns the number of items in a bit set enum
|
# Returns the number of items in a bit set enum
|
||||||
log2(float64(enumTy.high)).int + 1
|
log2(float64(enumTy.high)).int + 1
|
||||||
|
|
@ -95,8 +90,8 @@ type
|
||||||
data*: ptr UncheckedArray[T]
|
data*: ptr UncheckedArray[T]
|
||||||
|
|
||||||
template raiseEx*(ty: untyped, message: string, rc: Result): untyped =
|
template raiseEx*(ty: untyped, message: string, rc: Result): untyped =
|
||||||
## Raise an exception with a result error
|
## Raise an exception with a result description
|
||||||
raise newException(ty, message & ": " & rc.error)
|
raise newException(ty, message & ": " & rc.description)
|
||||||
|
|
||||||
template raiseEx*(ty: untyped, message: string): untyped =
|
template raiseEx*(ty: untyped, message: string): untyped =
|
||||||
## Raise an exception
|
## Raise an exception
|
||||||
|
|
|
||||||
2
src/nim.cfg
Normal file
2
src/nim.cfg
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
--path="../ext"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue