Skip to content

Commit 405d0b2

Browse files
authored
Merge pull request #92 from samdze/release/0.21.0
Release/0.21.0
2 parents 1a752d3 + 2c4ce20 commit 405d0b2

15 files changed

Lines changed: 251 additions & 57 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,3 @@ This project is a work in progress, here's what is missing right now:
178178
- various playdate.sound funcionalities (but FilePlayer, SamplePlayer and SoundSequence are available)
179179
- playdate.json, but you can use Nim std/json, which is very convenient
180180
- advanced playdate.lua features, but basic Lua interop is available
181-
- playdate.scoreboards, undocumented even in the official C API docs

playdate.nimble

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "0.20.0"
3+
version = "0.21.0"
44
author = "Samuele Zolfanelli"
55
description = "Playdate Nim bindings with extra features."
66
license = "MIT"

playdate_example/src/playdate_example.nim

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import playdate/api
33
const FONT_PATH = "/System/Fonts/Asheville-Sans-14-Bold.pft"
44
const NIM_IMAGE_PATH = "/images/nim_logo"
55
const PLAYDATE_NIM_IMAGE_PATH = "/images/playdate_nim"
6+
const BACKGROUND_MUSIC_PATH = "/audio/finally_see_the_light"
7+
const BACKGROUND_MUSIC_SAMPLE_RATE = 48_000
8+
const BACKGROUND_MUSIC_FADE_IN_SECONDS = 4.0
9+
const BACKGROUND_MUSIC_FADE_IN_SAMPLES = (BACKGROUND_MUSIC_SAMPLE_RATE * BACKGROUND_MUSIC_FADE_IN_SECONDS).int32
610

711
var font: LCDFont
812

@@ -80,9 +84,11 @@ proc handler(event: PDSystemEvent, keycode: uint) {.raises: [].} =
8084
except:
8185
playdate.system.logToConsole(getCurrentExceptionMsg())
8286
# Inline try/except
83-
filePlayer = try: playdate.sound.newFilePlayer("/audio/finally_see_the_light") except: nil
87+
filePlayer = try: playdate.sound.newFilePlayer(BACKGROUND_MUSIC_PATH) except: nil
8488

8589
filePlayer.play(0)
90+
fileplayer.volume = 0.0 # first set folume to 0%
91+
filePlayer.fadeVolume(1.0, 1.0, BACKGROUND_MUSIC_FADE_IN_SAMPLES, nil) # then fade to 100%
8692

8793
# Add a checkmark menu item that plays a sound when switched and unpaused
8894
discard playdate.system.addCheckmarkMenuItem("Checkmark", false,

src/playdate/api.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import std/importutils
66
import bindings/api
77
export api
88

9-
import graphics, system, file, sprite, display, sound, lua, json, utils, types, nineslice
10-
export graphics, system, file, sprite, display, sound, lua, json, utils, types, nineslice
9+
import graphics, system, file, sprite, display, sound, scoreboards, lua, json, utils, types, nineslice
10+
export graphics, system, file, sprite, display, sound, scoreboards, lua, json, utils, types, nineslice
1111

1212
macro initSDK*() =
1313
return quote do:

src/playdate/bindings/api.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{.push raises: [].}
22

3-
import graphics, system, file, display, sprite, sound, lua
3+
import graphics, system, file, display, sprite, sound, scoreboards, lua
44

55
type PlaydateAPI* {.importc: "PlaydateAPI", header: "pd_api.h".} = object
66
system* {.importc: "system".}: ptr PlaydateSys
@@ -9,6 +9,7 @@ type PlaydateAPI* {.importc: "PlaydateAPI", header: "pd_api.h".} = object
99
sprite* {.importc: "sprite".}: ptr PlaydateSprite
1010
display* {.importc: "display".}: ptr PlaydateDisplay
1111
sound* {.importc: "sound".}: ptr PlaydateSound
12+
scoreboards* {.importc: "scoreboards".}: ptr PlaydateScoreboards
1213
lua* {.importc: "lua".}: ptr PlaydateLua
1314
# json* {.importc: "json".}: ptr PlaydateJSON # Unavailable, use std/json
1415

src/playdate/bindings/scoreboards.nim

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,52 @@
22

33
import utils
44

5-
type PDScore* {.importc: "PDScore", header: "pd_api_scoreboards.h", bycopy.} = object
6-
rank* {.importc: "rank".}: uint32
7-
value* {.importc: "value".}: uint32
8-
player* {.importc: "player".}: cstring
9-
10-
type PDScoresList* {.importc: "PDScoresList", header: "pd_api_scoreboards.h", bycopy.} = object
11-
boardID* {.importc: "boardID".}: cstring
12-
count* {.importc: "count".}: cuint
13-
lastUpdated* {.importc: "lastUpdated".}: uint32
14-
playerIncluded* {.importc: "playerIncluded".}: cint
15-
limit* {.importc: "limit".}: cuint
16-
scores* {.importc: "scores".}: ptr PDScore
17-
18-
type PDBoard* {.importc: "PDBoard", header: "pd_api_scoreboards.h", bycopy.} = object
19-
boardID* {.importc: "boardID".}: cstring
20-
name* {.importc: "name".}: cstring
21-
22-
type PDBoardsList* {.importc: "PDBoardsList", header: "pd_api_scoreboards.h", bycopy.} = object
23-
count* {.importc: "count".}: cuint
24-
lastUpdated* {.importc: "lastUpdated".}: uint32
25-
boards* {.importc: "boards".}: ptr PDBoard
26-
27-
type AddScoreCallback* = proc (score: ptr PDScore; errorMessage: cstring) {.cdecl.}
28-
type PersonalBestCallback* = proc (score: ptr PDScore; errorMessage: cstring) {.cdecl.}
29-
type BoardsListCallback* = proc (boards: ptr PDBoardsList; errorMessage: cstring) {.cdecl.}
30-
type ScoresCallback* = proc (scores: ptr PDScoresList; errorMessage: cstring) {.cdecl.}
5+
type
6+
PDScoreRaw* {.importc: "PDScore", header: "pd_api.h", bycopy.} = object
7+
rank* {.importc: "rank".}: cuint
8+
value* {.importc: "value".}: cuint
9+
player* {.importc: "player".}: cstring
10+
11+
PDScorePtr* = ptr PDScoreRaw
12+
13+
PDScoresListRaw* {.importc: "PDScoresList", header: "pd_api.h", bycopy.} = object
14+
boardID* {.importc: "boardID".}: cstring
15+
count* {.importc: "count".}: cuint
16+
lastUpdated* {.importc: "lastUpdated".}: cuint
17+
playerIncluded* {.importc: "playerIncluded".}: cuint
18+
limit* {.importc: "limit".}: cuint
19+
scores* {.importc: "scores".}: ptr UncheckedArray[PDScoreRaw]
20+
21+
PDScoresListPtr* = ptr PDScoresListRaw
22+
23+
PDBoardRaw* {.importc: "PDBoard", header: "pd_api.h", bycopy.} = object
24+
boardID* {.importc: "boardID".}: cstring
25+
name* {.importc: "name".}: cstring
26+
27+
PDBoardsListRaw* {.importc: "PDBoardsList", header: "pd_api.h", bycopy.} = object
28+
count* {.importc: "count".}: cuint
29+
lastUpdated* {.importc: "lastUpdated".}: cuint
30+
boards* {.importc: "boards".}: ptr UncheckedArray[PDBoardRaw]
31+
32+
PDBoardsListPtr* = ptr PDBoardsListRaw
33+
34+
PersonalBestCallbackRaw* {.importc: "PersonalBestCallback", header: "pd_api.h".} = proc (score: PDScorePtr; errorMessage: cstring) {.cdecl.}
35+
AddScoreCallbackRaw* {.importc: "AddScoreCallback", header: "pd_api.h".} = proc (score: PDScorePtr; errorMessage: cstring) {.cdecl.}
36+
BoardsListCallbackRaw* = proc (boards: ptr PDBoardsListRaw; errorMessage: cstring) {.cdecl.}
37+
ScoresCallbackRaw* = proc (scores: ptr PDScoresListRaw; errorMessage: cstring) {.cdecl.}
3138

3239
sdktype:
3340
type PlaydateScoreboards* {.importc: "const struct playdate_scoreboards", header: "pd_api.h".} = object
34-
addScore* {.importc: "addScore".}: proc (boardId: cstring; value: uint32;
35-
callback: AddScoreCallback): cint {.cdecl.}
36-
getPersonalBest* {.importc: "getPersonalBest".}: proc (boardId: cstring;
37-
callback: PersonalBestCallback): cint {.cdecl.}
38-
freeScore* {.importc: "freeScore".}: proc (score: ptr PDScore) {.cdecl.}
39-
getScoreboards* {.importc: "getScoreboards".}: proc (
40-
callback: BoardsListCallback): cint {.cdecl.}
41+
getPersonalBestBinding* {.importc: "getPersonalBest".}: proc (boardId: cstring;
42+
callback: PersonalBestCallbackRaw): cint {.cdecl, raises: [].}
43+
addScoreBinding* {.importc: "addScore".}: proc (boardId: cstring; value: cuint;
44+
callback: AddScoreCallbackRaw): cint {.cdecl, raises: [].}
45+
freeScore* {.importc: "freeScore".}: proc (score: PDScorePtr) {.cdecl, raises: [].}
46+
getScoreboardsBinding* {.importc: "getScoreboards".}: proc (
47+
callback: BoardsListCallbackRaw): cint {.cdecl, raises: [].}
4148
freeBoardsList* {.importc: "freeBoardsList".}: proc (
42-
boardsList: ptr PDBoardsList) {.cdecl.}
43-
getScores* {.importc: "getScores".}: proc (boardId: cstring;
44-
callback: ScoresCallback): cint {.cdecl.}
49+
boardsList: PDBoardsListPtr) {.cdecl, raises: [].}
50+
getScoresBinding* {.importc: "getScores".}: proc (boardId: cstring;
51+
callback: ScoresCallbackRaw): cint {.cdecl, raises: [].}
4552
freeScoresList* {.importc: "freeScoresList".}: proc (
46-
scoresList: ptr PDScoresList) {.cdecl.}
53+
scoresList: PDScoresListPtr) {.cdecl, raises: [].}

src/playdate/bindings/sound.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ type PlaydateSoundFileplayer {.importc: "const struct playdate_sound_fileplayer"
3838
# start: cfloat; `end`: cfloat) {.cdecl.}
3939
# didUnderrun* {.importc: "didUnderrun".}: proc (player: ptr FilePlayer): cint {.cdecl.}
4040
setFinishCallback* {.importc: "setFinishCallback".}: proc (
41-
player: FilePlayerPtr; callback: PDSndCallbackProcRaw, userData: pointer = nil) {.cdecl, raises: [].}
41+
player: FilePlayerPtr; callback: PDSndCallbackProcRaw, userdata: pointer = nil) {.cdecl, raises: [].}
4242
# setLoopCallback* {.importc: "setLoopCallback".}: proc (player: ptr FilePlayer;
4343
# callback: SndCallbackProc) {.cdecl.}
4444
getOffset {.importc: "getOffset".}: proc (player: FilePlayerPtr): cfloat {.cdecl, raises: [].}
4545
# getRate* {.importc: "getRate".}: proc (player: ptr FilePlayer): cfloat {.cdecl.}
4646
# setStopOnUnderrun* {.importc: "setStopOnUnderrun".}: proc (
4747
# player: ptr FilePlayer; flag: cint) {.cdecl.}
48-
# fadeVolume* {.importc: "fadeVolume".}: proc (player: ptr FilePlayer; left: cfloat;
49-
# right: cfloat; len: int32T; finishCallback: SndCallbackProc) {.cdecl.}
48+
fadeVolume* {.importc: "fadeVolume".}: proc (player: FilePlayerPtr; left: cfloat;
49+
right: cfloat; len: cint; finishCallback: PDSndCallbackProcRaw, userdata: pointer = nil) {.cdecl, raises:[].}
5050
# setMP3StreamSource* {.importc: "setMP3StreamSource".}: proc (
5151
# player: ptr FilePlayer; dataSource: proc (data: ptr uint8T; bytes: cint;
5252
# userdata: pointer): cint {.cdecl.}; userdata: pointer; bufferLen: cfloat) {.
@@ -90,7 +90,7 @@ type PlaydateSoundSampleplayer {.importc: "const struct playdate_sound_samplepla
9090
setPlayRange* {.importc: "setPlayRange".}: proc (player: SamplePlayerPtr;
9191
start: cint; `end`: cint) {.cdecl, raises: [].}
9292
setFinishCallback* {.importc: "setFinishCallback".}: proc (
93-
player: SamplePlayerPtr; callback: PDSndCallbackProcRaw, userData: pointer = nil) {.cdecl, raises: [].}
93+
player: SamplePlayerPtr; callback: PDSndCallbackProcRaw, userdata: pointer = nil) {.cdecl, raises: [].}
9494
# setLoopCallback* {.importc: "setLoopCallback".}: proc (player: ptr SamplePlayer;
9595
# callback: SndCallbackProc) {.cdecl.}
9696
getOffset* {.importc: "getOffset".}: proc (player: SamplePlayerPtr): cfloat {.cdecl , raises: [].}

src/playdate/bindings/utils.nim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import macros
22

3+
iterator items*[T](rawField: ptr UncheckedArray[T], len: Natural): T =
4+
## iterate through a C array
5+
## To convert to a Nim seq:
6+
## `cArray.items(count).toSeq`
7+
for i in 0..<len:
8+
yield rawField[i]
9+
310
func toNimSymbol(typeSymbol: string): string =
411
case typeSymbol:
512
of "cint":

src/playdate/build/config.nim

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ when not compiles(task):
1111
import system/nimscript
1212

1313
const headlessTesting = defined(simulator) and declared(test)
14-
const nimbleTesting = not defined(simulator) and not defined(devide) and declared(test)
14+
const nimbleTesting = not defined(simulator) and not defined(device) and declared(test)
1515
const testing = headlessTesting or nimbleTesting
1616

17+
# Use the host OS for compilation. This is useful when running supporting development tools that import the playdate SDK or where the os module needs to be available.
18+
# This does not make the playdate api callable, only the types (header files) are available.
19+
const useHostOS = defined(useHostOS)
20+
1721
# Path to the playdate src directory when checked out locally
1822
const localPlaydatePath = currentSourcePath / "../../../../src"
1923

@@ -24,7 +28,7 @@ let nimblePlaydatePath =
2428
else:
2529
gorgeEx("nimble path playdate").output.split("\n")[0]
2630

27-
if not testing:
31+
if not testing and not useHostOS:
2832
switch("noMain", "on")
2933
switch("backend", "c")
3034
switch("mm", "arc")
@@ -45,7 +49,9 @@ switch("passC", "-Wno-unknown-pragmas")
4549
switch("passC", "-Wdouble-promotion")
4650
switch("passC", "-I" & sdkPath() / "C_API")
4751

48-
switch("os", "any")
52+
if not useHostOS:
53+
echo "Setting os to any"
54+
switch("os", "any")
4955
switch("define", "useMalloc")
5056
switch("define", "standalone")
5157
switch("threads", "off")
@@ -133,8 +139,8 @@ when defined(simulator):
133139
switch("passC", "-DTARGET_SIMULATOR=1")
134140
switch("passC", "-Wstrict-prototypes")
135141

136-
if nimbleTesting:
137-
# Compiling for tests.
142+
if useHostOS or nimbleTesting:
143+
# Compiling for host system environment.
138144
switch("define", "simulator")
139145
switch("nimcache", nimcacheDir() / "simulator")
140146

src/playdate/graphics.nim

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ proc set*(view: var BitmapView, x, y: int, color: LCDSolidColor) =
341341

342342
proc getDebugBitmap*(this: ptr PlaydateGraphics): LCDBitmap =
343343
privateAccess(PlaydateGraphics)
344-
return LCDBitmap(resource: this.getDebugBitmap(), free: true) # Who should manage this memory? Not clear. Auto-managed.
344+
return LCDBitmap(resource: this.getDebugBitmap(), free: false) # do not free: system owns this
345345

346346
proc copyFrameBufferBitmap*(this: ptr PlaydateGraphics): LCDBitmap =
347347
privateAccess(PlaydateGraphics)
@@ -411,9 +411,12 @@ proc set*(this: var LCDBitmap, x, y: int, color: LCDSolidColor = kColorBlack) =
411411
var data = this.getData
412412
data.set(x, y, color)
413413

414-
proc setStencilImage*(this: ptr PlaydateGraphics, bitmap: LCDBitmap, tile: bool) =
414+
proc setStencilImage*(this: ptr PlaydateGraphics, bitmap: LCDBitmap, tile: bool = false) =
415415
privateAccess(PlaydateGraphics)
416-
this.setStencilImage(bitmap.resource, if tile: 1 else: 0)
416+
if bitmap == nil:
417+
this.setStencilImage(nil, if tile: 1 else: 0)
418+
else:
419+
this.setStencilImage(bitmap.resource, if tile: 1 else: 0)
417420

418421
proc makeFont*(this: LCDFontData, wide: bool): LCDFont =
419422
privateAccess(PlaydateGraphics)

0 commit comments

Comments
 (0)