diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d9416a2..bcf66bf 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -110,4 +110,4 @@ jobs:
- name: Run headless test
working-directory: ./tests
- run: xvfb-run ../PlaydateSDK-*/bin/PlaydateSimulator playdate_tests.pdx
+ run: xvfb-run ../PlaydateSDK-*/bin/PlaydateSimulator playdate.pdx
diff --git a/README.md b/README.md
index 206ac85..d424ce7 100644
--- a/README.md
+++ b/README.md
@@ -45,11 +45,12 @@ This package is an independent bindings library, not affiliated with Panic.
You can quickly start using the bindings opening the `playdate_example` project included in this repository.
If you want to start from scratch, here are the steps to follow:
-1. If you haven't run it already, start by initializing your nimble package and follow the instructions:
+1. If you haven't done it already, start creating a folder (snake_case) and initializing your nimble package inside it running:
```
nimble init
```
+Choose `binary` as the package type.
2. Install the `playdate` package:
@@ -57,8 +58,7 @@ nimble init
nimble install playdate
```
-3. Move into your package directory.
-Add the `playdate` package as a dependency and configure the build tasks by running the following:
+3. Add the `playdate` package as a dependency and configure the build tasks by running the following:
```
echo 'requires "playdate"' >> *.nimble;
@@ -111,6 +111,11 @@ For simulator + device (pdx):
nimble all
```
+You can also build for simulator and launch it in one command:
+```sh
+nimble simulate
+```
+
The example project `playdate_example` also contains VSCode launch configurations to build, start and debug your Nim application from the editor.
Each project also contains a simple CMakeLists.txt as a starting point in case you'd want to add libraries or other external code.
diff --git a/playdate.nimble b/playdate.nimble
index 2a0e790..1a34866 100644
--- a/playdate.nimble
+++ b/playdate.nimble
@@ -1,6 +1,6 @@
# Package
-version = "0.9.0"
+version = "0.9.3"
author = "Samuele Zolfanelli"
description = "Playdate Nim bindings with extra features."
license = "MIT"
diff --git a/playdate_example/.vscode/launch.json b/playdate_example/.vscode/launch.json
index 3005e63..a248804 100644
--- a/playdate_example/.vscode/launch.json
+++ b/playdate_example/.vscode/launch.json
@@ -10,7 +10,7 @@
"name": "Debug PDX",
"program": "${env:PLAYDATE_SDK_PATH}/bin/Playdate Simulator",
"args": [
- "${workspaceFolder}/playdate_example.pdx"
+ "${workspaceFolder}/playdate.pdx"
],
"cwd": "${workspaceFolder}",
"osx": {
@@ -33,7 +33,7 @@
"program": "${env:PLAYDATE_SDK_PATH}/bin/Playdate Simulator",
"preLaunchTask": "Build Universal PDX",
"args": [
- "${workspaceFolder}/playdate_example.pdx"
+ "${workspaceFolder}/playdate.pdx"
],
"cwd": "${workspaceFolder}",
"osx": {
@@ -56,7 +56,7 @@
"program": "${env:PLAYDATE_SDK_PATH}/bin/Playdate Simulator",
"preLaunchTask": "Build Simulator PDX",
"args": [
- "${workspaceFolder}/playdate_example.pdx"
+ "${workspaceFolder}/playdate.pdx"
],
"cwd": "${workspaceFolder}",
"osx": {
diff --git a/playdate_example/CMakeLists.txt b/playdate_example/CMakeLists.txt
index 40765e6..d41bc8e 100644
--- a/playdate_example/CMakeLists.txt
+++ b/playdate_example/CMakeLists.txt
@@ -5,6 +5,7 @@
# $ENV{PLAYDATE_PROJECT_NAME}: the project name
# $ENV{PLAYDATE_MODULE_DIR}: the path to the installed playdate Nim module
# $ENV{NIM_CACHE_DIR}: the path to the project Nim cache files
+# $ENV{NIM_C_SOURCE_FILES}: list of semicolon-separated, Nim-generated C files that have to be compiled
# $ENV{NIM_INCLUDE_DIR}: the path to required Nim header files
cmake_minimum_required(VERSION 3.14)
@@ -15,4 +16,8 @@ set(CMAKE_C_STANDARD 11)
project($ENV{PLAYDATE_PROJECT_NAME} C ASM)
# Include the playdate module CMake configuration
-include($ENV{PLAYDATE_MODULE_DIR}/playdate.cmake)
\ No newline at end of file
+include($ENV{PLAYDATE_MODULE_DIR}/playdate.cmake)
+
+# Targets:
+# ${PLAYDATE_GAME_NAME}: simulator
+# ${PLAYDATE_GAME_DEVICE}: device
\ No newline at end of file
diff --git a/playdate_example/Source/audio/finally_see_the_light.wav b/playdate_example/source/audio/finally_see_the_light.wav
similarity index 100%
rename from playdate_example/Source/audio/finally_see_the_light.wav
rename to playdate_example/source/audio/finally_see_the_light.wav
diff --git a/playdate_example/Source/audio/jingle.wav b/playdate_example/source/audio/jingle.wav
similarity index 100%
rename from playdate_example/Source/audio/jingle.wav
rename to playdate_example/source/audio/jingle.wav
diff --git a/playdate_example/Source/images/nim_logo.png b/playdate_example/source/images/nim_logo.png
similarity index 100%
rename from playdate_example/Source/images/nim_logo.png
rename to playdate_example/source/images/nim_logo.png
diff --git a/playdate_example/Source/images/playdate_nim.png b/playdate_example/source/images/playdate_nim.png
similarity index 100%
rename from playdate_example/Source/images/playdate_nim.png
rename to playdate_example/source/images/playdate_nim.png
diff --git a/playdate_example/Source/json/data.json b/playdate_example/source/json/data.json
similarity index 100%
rename from playdate_example/Source/json/data.json
rename to playdate_example/source/json/data.json
diff --git a/playdate_example/Source/json/error.json b/playdate_example/source/json/error.json
similarity index 100%
rename from playdate_example/Source/json/error.json
rename to playdate_example/source/json/error.json
diff --git a/playdate_example/Source/pdxinfo b/playdate_example/source/pdxinfo
similarity index 100%
rename from playdate_example/Source/pdxinfo
rename to playdate_example/source/pdxinfo
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 40765e6..9a466cf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,6 +5,7 @@
# $ENV{PLAYDATE_PROJECT_NAME}: the project name
# $ENV{PLAYDATE_MODULE_DIR}: the path to the installed playdate Nim module
# $ENV{NIM_CACHE_DIR}: the path to the project Nim cache files
+# $ENV{NIM_C_SOURCE_FILES}: list of semicolon-separated, Nim-generated C files that have to be compiled
# $ENV{NIM_INCLUDE_DIR}: the path to required Nim header files
cmake_minimum_required(VERSION 3.14)
@@ -14,5 +15,9 @@ set(CMAKE_C_STANDARD 11)
# Setup the project and its name from the environment
project($ENV{PLAYDATE_PROJECT_NAME} C ASM)
-# Include the playdate module CMake configuration
-include($ENV{PLAYDATE_MODULE_DIR}/playdate.cmake)
\ No newline at end of file
+# Include the playdate module CMake configuration, this defines the targets
+include($ENV{PLAYDATE_MODULE_DIR}/playdate.cmake)
+
+# Targets:
+# ${PLAYDATE_GAME_NAME}: simulator
+# ${PLAYDATE_GAME_DEVICE}: device
\ No newline at end of file
diff --git a/src/playdate.cmake b/src/playdate.cmake
index d561ca2..100fe96 100644
--- a/src/playdate.cmake
+++ b/src/playdate.cmake
@@ -24,20 +24,18 @@ endif()
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
set(CMAKE_XCODE_GENERATE_SCHEME TRUE)
-file(GLOB nim_source_files "$ENV{NIM_CACHE_DIR}/*.c")
-
# Game Name Customization
-set(PLAYDATE_GAME_NAME $ENV{PLAYDATE_PROJECT_NAME})
-set(PLAYDATE_GAME_DEVICE $ENV{PLAYDATE_PROJECT_NAME})
+set(PLAYDATE_GAME_NAME $ENV{PLAYDATE_PROJECT_NAME}_simulator)
+set(PLAYDATE_GAME_DEVICE $ENV{PLAYDATE_PROJECT_NAME}_device)
# Include Nim required headers
include_directories($ENV{NIM_INCLUDE_DIR})
if (TOOLCHAIN STREQUAL "armgcc")
- add_executable(${PLAYDATE_GAME_DEVICE} ${nim_source_files})
+ add_executable(${PLAYDATE_GAME_DEVICE} $ENV{NIM_C_SOURCE_FILES})
target_link_libraries(${PLAYDATE_GAME_DEVICE} rdimon c m gcc nosys)
else()
- add_library(${PLAYDATE_GAME_NAME} SHARED ${nim_source_files})
+ add_library(${PLAYDATE_GAME_NAME} SHARED $ENV{NIM_C_SOURCE_FILES})
endif()
include(${SDK}/C_API/buildsupport/playdate.cmake)
@@ -51,67 +49,55 @@ if (TOOLCHAIN STREQUAL "armgcc")
TARGET ${PLAYDATE_GAME_DEVICE} POST_BUILD
COMMAND ${CMAKE_STRIP} --strip-unneeded -R .comment -g
${PLAYDATE_GAME_DEVICE}.elf
- -o ${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.elf
+ -o ${CMAKE_CURRENT_SOURCE_DIR}/source/pdex.elf
)
add_custom_command(
TARGET ${PLAYDATE_GAME_DEVICE} POST_BUILD
- COMMAND ${PDC} Source ${PLAYDATE_GAME_NAME}.pdx
+ COMMAND ${PDC} source playdate.pdx
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
set_property(
TARGET ${PLAYDATE_GAME_DEVICE} PROPERTY ADDITIONAL_CLEAN_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/${PLAYDATE_GAME_NAME}.pdx
+ ${CMAKE_CURRENT_SOURCE_DIR}/playdate.pdx
)
else ()
-
if (MSVC)
# MSVC not supported
message(FATAL_ERROR "MSVC is not supported! Use MinGW.")
-
+
elseif(MINGW)
target_compile_definitions(${PLAYDATE_GAME_NAME} PUBLIC _WINDLL=1)
- add_custom_command(
- TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_BINARY_DIR}/lib${PLAYDATE_GAME_NAME}.dll
- ${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.dll)
+ set(DYLIB_EXT "dll")
elseif(APPLE)
target_sources(${PLAYDATE_GAME_NAME} PRIVATE ${SDK}/C_API/buildsupport/setup.c)
- if(${CMAKE_GENERATOR} MATCHES "Xcode" )
- set(BUILD_SUB_DIR $/)
- set_property(TARGET ${PLAYDATE_GAME_NAME} PROPERTY XCODE_SCHEME_ARGUMENTS \"${CMAKE_CURRENT_SOURCE_DIR}/${PLAYDATE_GAME_NAME}.pdx\")
- set_property(TARGET ${PLAYDATE_GAME_NAME} PROPERTY XCODE_SCHEME_EXECUTABLE ${SDK}/bin/Playdate\ Simulator.app)
- endif()
-
- add_custom_command(
- TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUB_DIR}lib${PLAYDATE_GAME_NAME}.dylib
- ${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.dylib)
+ set(DYLIB_EXT "dylib")
elseif(UNIX)
target_sources(${PLAYDATE_GAME_NAME} PRIVATE ${SDK}/C_API/buildsupport/setup.c)
- add_custom_command(
- TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${CMAKE_CURRENT_BINARY_DIR}/lib${PLAYDATE_GAME_NAME}.so
- ${CMAKE_CURRENT_SOURCE_DIR}/Source/pdex.so)
+ set(DYLIB_EXT "so")
+
else()
message(FATAL_ERROR "Platform not supported!")
endif()
+ add_custom_command(
+ TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/${BUILD_SUB_DIR}lib${PLAYDATE_GAME_NAME}.${DYLIB_EXT}
+ ${CMAKE_CURRENT_SOURCE_DIR}/source/pdex.${DYLIB_EXT})
+
set_property(
TARGET ${PLAYDATE_GAME_NAME} PROPERTY ADDITIONAL_CLEAN_FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/${PLAYDATE_GAME_NAME}.pdx
+ ${CMAKE_CURRENT_SOURCE_DIR}/playdate.pdx
)
add_custom_command(
TARGET ${PLAYDATE_GAME_NAME} POST_BUILD
- COMMAND ${PDC} ${CMAKE_CURRENT_SOURCE_DIR}/Source
- ${CMAKE_CURRENT_SOURCE_DIR}/${PLAYDATE_GAME_NAME}.pdx)
+ COMMAND ${PDC} ${CMAKE_CURRENT_SOURCE_DIR}/source
+ ${CMAKE_CURRENT_SOURCE_DIR}/playdate.pdx)
endif ()
diff --git a/src/playdate/build/config.nim b/src/playdate/build/config.nim
index 0eb7086..3b6e5ea 100644
--- a/src/playdate/build/config.nim
+++ b/src/playdate/build/config.nim
@@ -37,6 +37,7 @@ when defined(simulator):
switch("checks", "on")
switch("index", "on")
switch("debuginfo", "on")
+ switch("stackTrace", "on")
switch("lineTrace", "on")
switch("lineDir", "on")
switch("debugger", "native")
diff --git a/src/playdate/build/nimble.nim b/src/playdate/build/nimble.nim
index d352b15..9e2787d 100644
--- a/src/playdate/build/nimble.nim
+++ b/src/playdate/build/nimble.nim
@@ -1,4 +1,4 @@
-import sequtils, strutils, os
+import sequtils, strutils, os, json
# This file is designed to be `included` directly from a nimble file, which will make `switch` and `task`
# implicitly available. This block just fixes auto-complete in IDEs
@@ -9,12 +9,16 @@ type Target = enum
simulator = "simulator"
device = "device"
+type CompileInstructions = object
+ compile: seq[array[2, string]]
+
+type BuildFail = object of Defect
+
+
proc nimble(args: varargs[string]) =
## Executes nimble with the given set of arguments
exec @["nimble"].concat(args.toSeq).join(" ")
-type BuildFail = object of Defect
-
proc playdatePath(): string =
## Returns the path of the playdate nim module
var (paths, exitCode) = gorgeEx("nimble path playdate")
@@ -30,7 +34,7 @@ proc playdatePath(): string =
proc pdxName(): string =
## The name of the pdx file to generate
- projectName() & ".pdx"
+ "playdate" & ".pdx"
const SDK_ENV_VAR = "PLAYDATE_SDK_PATH"
@@ -53,15 +57,34 @@ proc sdkPath*(): string =
raise BuildFail.newException("SDK environment variable is not set: " & SDK_ENV_VAR)
+proc simulatorPath(open: bool = false): string =
+ if defined(windows):
+ return sdkPath() / "bin" / "PlaydateSimulator.exe"
+ elif defined(macosx):
+ return (if open: "open " else: "") & sdkPath() / "bin" / "Playdate\\ Simulator.app"
+ else:
+ return sdkPath() / "bin" / "PlaydateSimulator"
+
+proc filesToCompile(target: Target): seq[string] =
+ let jsonString = readFile(nimcacheDir() / $target / projectName() & ".json")
+ let instructions = parseJson(jsonString).to(CompileInstructions)
+
+ return instructions.compile.map(
+ proc(entry: array[2, string]): string =
+ return entry[0]
+ )
+
proc build(target: Target) =
## Builds a target
+ let buildDir = "build" / $target
+
putEnv(SDK_ENV_VAR, sdkPath())
putEnv("PLAYDATE_MODULE_DIR", playdatePath())
putEnv("PLAYDATE_PROJECT_NAME", projectName())
putEnv("NIM_INCLUDE_DIR", getCurrentCompilerExe().parentDir.parentDir / "lib")
+ putEnv("NIM_C_SOURCE_FILES", filesToCompile(target).join(";").replace(DirSep, '/'))
putEnv("NIM_CACHE_DIR", (nimcacheDir() / $target).replace(DirSep, '/'))
-
- let buildDir = "build" / $target
+
mkDir(buildDir)
withDir(buildDir):
case target:
@@ -70,10 +93,9 @@ proc build(target: Target) =
exec("cmake ../.. -DCMAKE_BUILD_TYPE=Debug" & " -G \"MinGW Makefiles\"")
else:
exec("cmake ../.. -DCMAKE_BUILD_TYPE=Debug" & " -G \"Unix Makefiles\"")
- exec("make")
of device:
exec("cmake ../.. -DCMAKE_BUILD_TYPE=Release" & " -G \"Unix Makefiles\" --toolchain=" & (sdkPath() / "C_API" / "buildsupport" / "arm.cmake"))
- exec("make")
+ exec("make")
proc taskArgs(taskName: string): seq[string] =
let args = command_line_params()
@@ -85,46 +107,46 @@ task clean, "Clean the project folders":
let args = taskArgs("clean")
if args.contains("--simulator"):
- rmDir(nimcacheDir() / "simulator")
- rmDir("build" / "simulator")
- rmFile("Source" / "pdex.dylib")
- rmFile("Source" / "pdex.dll")
- rmFile("Source" / "pdex.so")
+ rmDir(nimcacheDir() / $Target.simulator)
+ rmDir("build" / $Target.simulator)
+ rmFile("source" / "pdex.dylib")
+ rmFile("source" / "pdex.dll")
+ rmFile("source" / "pdex.so")
elif args.contains("--device"):
- rmDir(nimcacheDir() / "device")
- rmDir("build" / "device")
- rmFile("Source" / "pdex.bin")
- rmFile("Source" / "pdex.elf")
+ rmDir(nimcacheDir() / $Target.device)
+ rmDir("build" / $Target.device)
+ rmFile("source" / "pdex.bin")
+ rmFile("source" / "pdex.elf")
else:
rmDir(nimcacheDir())
rmDir(pdxName())
rmDir("build")
- rmFile("Source" / "pdex.bin")
- rmFile("Source" / "pdex.dylib")
- rmFile("Source" / "pdex.dll")
- rmFile("Source" / "pdex.so")
- rmFile("Source" / "pdex.elf")
+ rmFile("source" / "pdex.bin")
+ rmFile("source" / "pdex.dylib")
+ rmFile("source" / "pdex.dll")
+ rmFile("source" / "pdex.so")
+ rmFile("source" / "pdex.elf")
task cdevice, "Generate C files for the device":
nimble "-d:device", "build"
-task csim, "Generate C files for the simulator":
+task csimulator, "Generate C files for the simulator":
nimble "-d:simulator", "build"
task simulator, "Build for the simulator":
- nimble "-d:simulator", "build"
+ nimble "csimulator"
build Target.simulator
task simulate, "Build and run in the simulator":
nimble "simulator"
- exec( (sdkPath() / "bin" / "PlaydateSimulator") & " " & pdxName())
+ exec (simulatorPath(open = true) & " " & pdxName())
task device, "Build for the device":
- nimble "-d:device", "build"
+ nimble "cdevice"
build Target.device
task all, "Build for both the simulator and the device":
- nimble "csim"
+ nimble "csimulator"
build Target.simulator
nimble "cdevice"
build Target.device
@@ -138,10 +160,10 @@ task setup, "Initialize the build structure":
if not fileExists("CMakeLists.txt"):
cpFile(playdatePath() / "CMakeLists.txt", "CMakeLists.txt")
- if not dirExists("Source"):
- mkDir "Source"
+ if not dirExists("source"):
+ mkDir "source"
- if not fileExists("Source/pdxinfo"):
+ if not fileExists("source/pdxinfo"):
let cartridgeName = projectName()
.replace("_", " ")
.split(" ")
@@ -158,7 +180,7 @@ task setup, "Initialize the build structure":
.replace("-", "")
.replace("_", "")
writeFile(
- "Source/pdxinfo",
+ "source/pdxinfo",
[
"name=" & cartridgeName,
"author=" & author,
@@ -170,5 +192,5 @@ task setup, "Initialize the build structure":
if not fileExists( ".gitignore"):
".gitignore".writeFile([
pdxName(),
- "Source/pdex.*"
+ "source/pdex.*"
].join("\n"))
diff --git a/tests/Source/main.lua b/tests/source/main.lua
similarity index 100%
rename from tests/Source/main.lua
rename to tests/source/main.lua
diff --git a/tests/Source/pdxinfo b/tests/source/pdxinfo
similarity index 100%
rename from tests/Source/pdxinfo
rename to tests/source/pdxinfo