Created
January 22, 2023 18:07
-
-
Save Eiyeron/92aba96dfb87da3fd71092ffa4d23f90 to your computer and use it in GitHub Desktop.
PlayDate CMake template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.14) | |
set(CMAKE_C_STANDARD 11) | |
set(ENVSDK $ENV{PLAYDATE_SDK_PATH}) | |
if (NOT ${ENVSDK} STREQUAL "") | |
# Convert path from Windows | |
file(TO_CMAKE_PATH ${ENVSDK} SDK) | |
else() | |
execute_process( | |
COMMAND bash -c "egrep '^\\s*SDKRoot' $HOME/.Playdate/config" | |
COMMAND head -n 1 | |
COMMAND cut -c9- | |
OUTPUT_VARIABLE SDK | |
OUTPUT_STRIP_TRAILING_WHITESPACE | |
) | |
endif() | |
if (NOT EXISTS ${SDK}) | |
message(FATAL_ERROR "SDK Path not found; set ENV value PLAYDATE_SDK_PATH") | |
return() | |
endif() | |
set(CMAKE_CONFIGURATION_TYPES "Debug;Release") | |
# Compilation-time sprite generation | |
# If you don't have Aseprite in your Path, you can uncomment this line and hardcode your executable's path here. | |
# I don't know yet how to make configurable variables. | |
# set(ASEPRITE "C:/Program Files/Aseprite/Aseprite.exe") | |
find_program(ASEPRITE "aseprite") | |
if (NOT EXISTS ${ASEPRITE}) | |
message(FATAL_ERROR "Aseprite not found. Please set in your PATH or configure it manually.") | |
return() | |
endif() | |
# The source folder is processed by the PlayDate SDK to create the assets in the .pdx folder. | |
# I usually keep my assets' "source files" into another folder. | |
# Those two paths are freely editable as long as you don't put them in the project's PDX folder. | |
set (ASSET_SOURCE "${CMAKE_SOURCE_DIR}/assets_source") | |
set (SPRITE_FOLDER "${CMAKE_SOURCE_DIR}/Source/img") | |
add_library(sprites INTERFACE) | |
# Create build step to convert an .aseprite file into one or multiple .PNGs. | |
function(add_sprites) | |
cmake_parse_arguments( | |
PARSE_ARGV 0 | |
"ARGS" | |
"BITMAP_TABLE" # list of names of the boolean arguments (only defined ones will be true) | |
"IN_FILE;OUT_PATH" # list of names of mono-valued arguments | |
"LAYERS" # list of names of multi-valued arguments (output variables are lists) | |
) | |
if (ARGS_UNPARSED_ARGUMENTS) | |
message(ERROR "Remaining : ${ARGS_UNPARSED_ARGUMENTS}") | |
endif(ARGS_UNPARSED_ARGUMENTS) | |
if (NOT ARGS_IN_FILE) | |
message(FATAL_ERROR "Missing sprite input file") | |
endif(NOT ARGS_IN_FILE) | |
if (NOT ARGS_OUT_PATH) | |
message(FATAL_ERROR "Missing sprite output path") | |
endif(NOT ARGS_OUT_PATH) | |
if(ARGS_LAYERS) | |
list(TRANSFORM ARGS_LAYERS PREPEND "--layer=\"") | |
list(TRANSFORM ARGS_LAYERS APPEND "\"") | |
endif(ARGS_LAYERS) | |
if (ARGS_BITMAP_TABLE) | |
# Create JSON file and open up | |
file(RELATIVE_PATH local_path "${CMAKE_SOURCE_DIR}/Source" ${ARGS_OUT_PATH}) | |
get_filename_component(json_path "${CMAKE_CURRENT_BINARY_DIR}/${local_path}.json" ABSOLUTE) | |
get_filename_component(json_dir "${json_path}" DIRECTORY) | |
make_directory(${json_dir}) | |
execute_process(COMMAND "${ASEPRITE}" -b "${ARGS_IN_FILE}" "--data=${json_path}" --format=json) | |
file(READ ${json_path} sprite_data) | |
string(JSON sprite_num_frames LENGTH ${sprite_data} "frames") | |
# Append sprites to lists (global for dependency and local for rule) | |
foreach(i RANGE 1 ${sprite_num_frames}) | |
list(APPEND sprite_frames "${ARGS_OUT_PATH}-${i}.png") | |
set(tiles "${tiles}" "${ARGS_OUT_PATH}-${i}.png" PARENT_SCOPE) | |
endforeach() | |
# Create command | |
add_custom_command( | |
OUTPUT ${sprite_frames} | |
COMMAND "${ASEPRITE}" -b "${ARGS_IN_FILE}" ${ARGS_LAYERS} --save-as="${ARGS_OUT_PATH}"-{frame1}.png | |
DEPENDS "${ARGS_IN_FILE}") | |
else() | |
set (single_sprites ${single_sprites} "${ARGS_OUT_PATH}.png" PARENT_SCOPE) | |
add_custom_command( | |
OUTPUT ${ARGS_OUT_PATH}.png | |
COMMAND "${ASEPRITE}" -b "${ARGS_IN_FILE}" ${ARGS_LAYERS} --save-as="${ARGS_OUT_PATH}".png | |
DEPENDS "${ARGS_IN_FILE}") | |
endif(ARGS_BITMAP_TABLE) | |
endfunction() | |
# Sample add_sprites example | |
add_sprites(BITMAP_TABLE | |
IN_FILE "${ASSET_SOURCE}/bitmap_table.aseprite" | |
OUT_PATH "${SPRITE_FOLDER}/my-filtered-sprite-as-a-table" | |
LAYERS "ALayer" "AnotherLayer" | |
) | |
add_sprites( | |
IN_FILE "${ASSET_SOURCE}/single_sprite.aseprite" | |
OUT_PATH "${SPRITE_FOLDER}/a-single-sprite-with-all-visible-layers") | |
add_sprites( | |
IN_FILE "${ASSET_SOURCE}/single_sprite.aseprite" | |
OUT_PATH "${SPRITE_FOLDER}/a-single-sprite-with-one-layer" | |
LAYERS "SomeLayer") | |
target_sources(sprites PRIVATE ${tiles} ${single_sprites}) | |
# Game Name Customization | |
set(PLAYDATE_GAME_NAME <put_your_project_name_here>) | |
set(PLAYDATE_GAME_DEVICE <put_your_project_name_here>_DEVICE) | |
project(${PLAYDATE_GAME_NAME} C ASM) | |
set(PROJECT_SRC | |
<add_your_source_here> | |
) | |
if (TOOLCHAIN STREQUAL "armgcc") | |
# Coming from https://devforum.play.date/t/doom-on-playdate/852/27 | |
# On Windows I have linking issues revolving around missing libc symbols. | |
# I hope this will fix the issue without breaking everything. | |
add_link_options(-specs=nano.specs -specs=nosys.specs) | |
add_executable(${PLAYDATE_GAME_DEVICE} ${SDK}/C_API/buildsupport/setup.c ${PROJECT_SRC}) | |
add_dependencies(${PLAYDATE_GAME_DEVICE} sprites) | |
else() | |
add_library(${PLAYDATE_GAME_NAME} SHARED ${PROJECT_SRC}) | |
add_dependencies(${PLAYDATE_GAME_NAME} sprites) | |
# I'm tired to hear about Spectre mitigation on a PlayDate DLL. | |
target_compile_options(${PLAYDATE_GAME_NAME} PRIVATE -Qspectre- -wd5045 -wd4820) | |
endif() | |
include(${SDK}/C_API/buildsupport/playdate_game.cmake) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment