Compare commits

...

21 commits

Author SHA1 Message Date
Joey
01dda9d2ce
Update README.md 2019-09-07 08:38:04 -06:00
Joey Yakimowich-Payne
497a079020 Version bump 2018-09-29 11:12:21 -06:00
Joey Yakimowich-Payne
71d0f65903 Fix graphics init error 2018-09-29 11:11:32 -06:00
Joey Yakimowich-Payne
4b7874c837 Fix more build script issues 2018-09-29 11:10:42 -06:00
Joey Yakimowich-Payne
8937928b3e Update config file for new libnx 2018-09-27 20:17:30 -06:00
Joey
09b93cef62
Update README.md 2018-07-20 17:19:24 +09:00
Joey
075e6d34b0
Update README.md 2018-07-20 17:15:18 +09:00
Joey Yakimowich-Payne
6d465e4de1 Make buildexamples use dkp for windows 2018-07-20 17:12:06 +09:00
Joey Yakimowich-Payne
65299fc325 Bump version 2018-07-20 17:02:02 +09:00
Joey Yakimowich-Payne
0bddb6f1ef Fix more windows issues 2018-07-20 17:00:39 +09:00
Joey Yakimowich-Payne
fb136ae95a Bump version 2018-07-18 11:31:57 +09:00
Joey Yakimowich-Payne
291abf3249 Add template for error handling and fix console printing 2018-07-18 11:31:13 +09:00
Joey Yakimowich-Payne
3fff14bd0b Update versions 2018-07-18 11:07:52 +09:00
Joey Yakimowich-Payne
626b66b8d7 Fix issues with latest Nim devel compiler 2018-07-18 11:04:09 +09:00
Joey
1955c8d3ec
Update libnx.nimble 2018-07-15 17:39:33 +09:00
Joey
0efc498286
Update README.md 2018-07-15 17:23:31 +09:00
Joey
8e556a448b
Update README.md 2018-07-15 17:23:02 +09:00
Joey Yakimowich-Payne
919ff32b1b Add windows support 2018-07-15 15:54:01 +09:00
Joey Yakimowich-Payne
a66af737d8 Make nimble windows friendly 2018-07-14 11:08:25 +09:00
Joey
ea55f461b5
Update README.md 2018-07-13 21:52:03 +09:00
Joey Yakimowich-Payne
92a3e69cce Change requires 2018-07-13 21:10:48 +09:00
15 changed files with 224 additions and 277 deletions

View file

@ -1,21 +1,36 @@
# 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 [here](https://github.com/jyapayne/Nim/tree/nintendo_switch_support) until the PR is accepted. 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.
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: 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.
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:
##Install ```bash
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 "https://github.com/jyapayne/nimgenEx#head" nimble install nimgen@#head
nimble install nimble install
``` ```

View file

@ -1,4 +0,0 @@
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")

View file

@ -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
proc main() = mainFunction:
graphics.initDefault() graphics.initDefault()
console.init() console.init()
@ -43,5 +43,3 @@ proc main() =
if ControllerKey.Plus in keysDown: if ControllerKey.Plus in keysDown:
break break
main()

View file

@ -2,7 +2,7 @@ import sets
import libnx/[graphics, console, app, input] import libnx/[graphics, console, app, input]
proc main() = mainFunction:
initDefault() initDefault()
console.init() console.init()
@ -15,5 +15,3 @@ proc main() =
if ControllerKey.Plus in keysDown: if ControllerKey.Plus in keysDown:
break break
main()

View file

@ -1,23 +1,39 @@
# Package # Package
version = "0.1.6" version = "0.2.2"
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", "https://github.com/genotrance/nimgen#head" requires "nim >= 0.18.1", "nimgen#dc9943a22c9c8f6a5a6a92f0055e1de4dfaf87d2"
requires "https://github.com/jyapayne/switch-build#head" requires "switch_build >= 0.1.3"
task setup, "Download and generate bindings": task setup, "Download and generate bindings":
echo "Building libnx..." echo "Building libnx..."
exec "nimgen libnxGen.cfg" exec prefix & "nimgen libnxGen.cfg"
task buildExamples, "Build switch examples": task buildExamples, "Build switch examples":
exec "switch_build --libnxPath='" & thisDir() & "/src/libnx/wrapper/nx/' --author='jyapayne' --version='1.0.0' examples/helloworld/helloworld.nim" if detectOs(Windows):
exec "switch_build --libnxPath='" & thisDir() & "/src/libnx/wrapper/nx/' --author='jyapayne' --version='1.0.0' examples/accounts/account_ex.nim" let devkitPath = getEnv("DEVKITPRO")
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()

View file

@ -8,26 +8,63 @@ 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/kernel"
"${output}/nx/include/switch/services"
"${output}/nx/include/switch/audio" "${output}/nx/include/switch/audio"
"${output}/nx/include/switch/gfx" "${output}/nx/include/switch/display"
"${output}/nx/include/switch/kernel"
"${output}/nx/include/switch/nvidia"
"${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=con)" rename = "$replace(console=cons)"
search = "_Bool"
replace = "bool"
wildcard.2 = "*.h" wildcard.2 = "*.h"
@ -68,10 +105,8 @@ replace.cdecl = "cdecl"
[n.prepare] [n.prepare]
git = "https://github.com/switchbrew/libnx" git = "https://github.com/switchbrew/libnx"
execute = """ execute-lin = """cd ${output}; make;"""
cd ${output} execute-mac = """cd ${output}; make;"""
make
"""
[n.post] [n.post]
reset=true reset=true
@ -81,56 +116,21 @@ 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,6 +169,26 @@ 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"
@ -313,7 +333,12 @@ prepend.o = """
import libnx/ext/integer128 import libnx/ext/integer128
""" """
[con.nim] [fence.nim]
prepend.o = """
import libnx/wrapper/types
"""
[cons.nim]
search.o = "type\n" search.o = "type\n"
prepend.o = """ prepend.o = """
@ -349,11 +374,16 @@ 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"

View file

@ -53,7 +53,7 @@ proc init() =
if code.failed: if code.failed:
raiseEx( raiseEx(
AccountInitError, AccountInitError,
"Error, account api could not be initialized: " & code.description "Error, account api could not be initialized", code
) )
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.description) raiseEx(AccountImageSizeError, "Error, could not get image size", code)
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.description) raiseEx(AccountImageSizeError, "Error, could not get image size", res)
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.description) raiseEx(AccountUserProfileError, "Error, could not get user profile", res)
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.description) raiseEx(AccountImageLoadError, "Error, could not load image", res)
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.description) raiseEx(AccountUserDataError, "Error, could not get user data", res)
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.description) raiseEx(AccountActiveUserError, "Error, could not get active user ID", res)
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.description) raiseEx(AccountUserDataError, "Error, could not get user data", res)
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.description "Error, could not get account profile", res
) )
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.description "Error, could not get user count", res
) )
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.description "Error, could not list users", res
) )
for i in 0 ..< usersReturned.int: for i in 0 ..< usersReturned.int:

View file

@ -1,8 +1,40 @@
import libnx/graphics, libnx/wrapper/hid, libnx/wrapper/applet import libnx/graphics, libnx/input, 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():
hidScanInput() scanInput()
code code

View file

@ -1,4 +0,0 @@
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")

View file

@ -1,6 +1,6 @@
import libnx/wrapper/con import macros, strutils, sets
import libnx/wrapper/cons
import libnx/utils import libnx/utils
import macros, strutils
type type
@ -37,18 +37,19 @@ type
tabSize*: int tabSize*: int
fg*: int fg*: int
bg*: int bg*: int
flags*: set[Style] flags*: HashSet[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
@ -64,7 +65,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 = {} result.flags = initSet[Style]()
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()
@ -86,20 +87,21 @@ 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 =
consoleSelect(console.pcon).toConsole() currentConsole = consoleInit(console.pcon).toConsole()
return currentConsole
proc init*(console: Console = nil): Console {.discardable.} = proc init*(console: Console): Console {.discardable.} =
var newCon = console currentConsole = consoleInit(console.pcon).toConsole()
if newCon.isNil: return currentConsole
newCon = new(Console)
let pcon = consoleInit(newCon.pcon) proc init*(): Console {.discardable.} =
newCon = pcon.toConsole() currentConsole = consoleInit(nil).toConsole()
return newCon return currentConsole
proc debugInit*(device: DebugDevice) = proc debugInit*(device: DebugDevice) =
if device == ThreeDMOO: if device == ThreeDMOO:
@ -110,17 +112,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, `$`]) =
setPrintPos(pos) echo CONSOLE_ESC("2K"), (CONSOLE_ESC("$#;$#H") % [$pos.row, $pos.col]), args.join("")
echo ("\x1b[$#;$#H" % [$pos[0], $pos[1]]), args.join("") currentConsole.pcon.cursorX = pos.col.int32
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`` or ``setPrintPos`` ## Will print at the previously set printPos using ``printAt``
## 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

View file

@ -2,10 +2,12 @@ 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
@ -53,7 +55,12 @@ var enabled = false
## ##
proc initDefault*() = proc initDefault*() =
if not enabled: if not enabled:
gfxInitDefault() let code = gfxInitDefault().newResult
if code.failed:
raiseEx(
GraphicsInitError,
"Error, graphics could not be initialized", code
)
enabled = true enabled = true
## * ## *
@ -184,10 +191,6 @@ 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) =

View file

@ -26,136 +26,6 @@ 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
@ -165,7 +35,6 @@ 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()
@ -421,7 +290,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:

View file

@ -1,3 +1,4 @@
import strutils
import import
libnx/wrapper/result, libnx/wrapper/result,
libnx/wrapper/types libnx/wrapper/types
@ -5,7 +6,7 @@ import
type type
Module {.pure.} = enum Module {.pure.} = enum
Invalid = 0, # This is just so the nim compiler is happy Success = 0,
Kernel = 1, Kernel = 1,
Libnx = 345, Libnx = 345,
LibnxNvidia = 348 LibnxNvidia = 348
@ -13,16 +14,8 @@ type
Result* = ref object Result* = ref object
code*: uint32 code*: uint32
module*: string module*: string
description*: string kind*: Module
case kind*: Module error*: string
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
@ -98,8 +91,6 @@ 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)
@ -108,20 +99,18 @@ proc newResult*(code: uint32): Result =
let descCode = code.R_DESCRIPTION let descCode = code.R_DESCRIPTION
var description = "" var error = "Unknown error: module: $# description: $#" %
[$moduleCode, $descCode]
try: try:
case module case module
of Module.Invalid: of Module.Success:
discard return
of Module.Kernel: of Module.Kernel:
result.kernelError = KernelError(descCode) error = $KernelError(descCode)
description = $result.kernelError
of Module.Libnx: of Module.Libnx:
result.libnxError = LibnxError(descCode) error = $LibnxError(descCode)
description = $result.libnxError
of Module.LibnxNvidia: of Module.LibnxNvidia:
result.libnxNvidiaError = LibnxNvidiaError(descCode) error = $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
@ -130,4 +119,4 @@ proc newResult*(code: uint32): Result =
echo "DescCode: " & $descCode echo "DescCode: " & $descCode
result.module = $module result.module = $module
result.description = description result.error = error

View file

@ -1,6 +1,11 @@
import macros, strutils, math import macros, strutils, math, hashes
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
@ -90,8 +95,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 description ## Raise an exception with a result error
raise newException(ty, message & ": " & rc.description) raise newException(ty, message & ": " & rc.error)
template raiseEx*(ty: untyped, message: string): untyped = template raiseEx*(ty: untyped, message: string): untyped =
## Raise an exception ## Raise an exception

View file

@ -1,2 +0,0 @@
--path="../ext"