From d56cc3cb40d29e331356cee95377e341642a9f5f Mon Sep 17 00:00:00 2001 From: MrHuu Date: Tue, 19 Nov 2019 00:51:39 +0100 Subject: [PATCH] [3DS] CMake instructions --- .circleci/config.yml | 21 + CMake/ctr/FindCTRULIB.cmake | 48 ++ CMake/ctr/Tools3DS.cmake | 511 ++++++++++++++++++ CMake/ctr/bin2s_header.h.in | 3 + CMake/ctr/devkitarm-libctru.cmake | 63 +++ CMake/ctr/modules/FindCITRO3D.cmake | 61 +++ CMake/ctr/modules/FindFreetype.cmake | 54 ++ CMake/ctr/modules/FindMAD.cmake | 60 ++ CMake/ctr/modules/FindMikMod.cmake | 60 ++ CMake/ctr/modules/FindOgg.cmake | 60 ++ CMake/ctr/modules/FindPNG.cmake | 60 ++ CMake/ctr/modules/FindVorbis.cmake | 66 +++ CMake/ctr/modules/FindZLIB.cmake | 51 ++ CMake/ctr/modules/LibFindMacros.cmake | 265 +++++++++ .../ctr/modules/try_add_imported_target.cmake | 15 + CMakeLists.txt | 63 ++- Packaging/ctr/build.sh | 57 ++ README.md | 31 ++ 18 files changed, 1545 insertions(+), 4 deletions(-) create mode 100644 CMake/ctr/FindCTRULIB.cmake create mode 100644 CMake/ctr/Tools3DS.cmake create mode 100644 CMake/ctr/bin2s_header.h.in create mode 100644 CMake/ctr/devkitarm-libctru.cmake create mode 100644 CMake/ctr/modules/FindCITRO3D.cmake create mode 100644 CMake/ctr/modules/FindFreetype.cmake create mode 100644 CMake/ctr/modules/FindMAD.cmake create mode 100644 CMake/ctr/modules/FindMikMod.cmake create mode 100644 CMake/ctr/modules/FindOgg.cmake create mode 100644 CMake/ctr/modules/FindPNG.cmake create mode 100644 CMake/ctr/modules/FindVorbis.cmake create mode 100644 CMake/ctr/modules/FindZLIB.cmake create mode 100644 CMake/ctr/modules/LibFindMacros.cmake create mode 100644 CMake/ctr/modules/try_add_imported_target.cmake create mode 100644 Packaging/ctr/build.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 85f5d949c..e0bb7a3bc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -112,6 +112,26 @@ jobs: - run: PKG_CONFIG_PATH=/opt/m68k-amigaos/lib/pkgconfig/:/opt/m68k-amigaos/share/pkgconfig/ cmake -S. -Bbuild -DM68K_CPU=68040 -DM68K_FPU=hard -DM68K_COMMON="-s -ffast-math -O3 -noixemul -D__BIG_ENDIAN__ -D__AMIGA__ -fpermissive" .. - run: cd build && make -j$(nproc) - store_artifacts: {path: ./build/devilutionx, destination: devilutionx_m68k} + 3ds: + docker: + - image: devkitpro/devkitarm:latest + working_directory: ~/repo + steps: + - checkout + - run: echo deb http://deb.debian.org/debian stretch-backports main > /etc/apt/sources.list.d/debian-backports.list + - run: echo deb http://deb.debian.org/debian stretch-backports-sloppy main >> /etc/apt/sources.list.d/debian-backports.list + - run: apt-get update && apt-get install -y -t 'stretch-backports*' cmake unzip + - run: dkp-pacman -Syu --noconfirm + - run: dkp-pacman -S --needed --noconfirm --quiet devkitpro-pkgbuild-helpers + - run: wget https://github.com/Steveice10/bannertool/releases/download/1.1.0/bannertool.zip + - run: unzip -j "bannertool.zip" "linux-x86_64/bannertool" -d "/opt/devkitpro/tools/bin" + - run: wget https://github.com/jakcron/Project_CTR/releases/download/v0.16/makerom_016_ctrtool.zip + - run: unzip -j "makerom_016_ctrtool.zip" "Ubuntu/makerom" -d "/opt/devkitpro/tools/bin" + - run: sudo chmod +rx /opt/devkitpro/tools/bin/makerom + - run: cd build && cmake .. -DNIGHTLY_BUILD=ON -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/3ds.cmake + - run: cd build && cmake --build . -j $(nproc) + - store_artifacts: {path: ./build/devilutionx.3dsx, destination: devilutionx.3dsx} + - store_artifacts: {path: ./build/devilutionx.cia, destination: devilutionx.cia} workflows: version: 2 @@ -124,4 +144,5 @@ workflows: - windows_x64 - linux_x86_64_sdl1 - switch + - 3ds - amigaos-m68k diff --git a/CMake/ctr/FindCTRULIB.cmake b/CMake/ctr/FindCTRULIB.cmake new file mode 100644 index 000000000..465ff6c66 --- /dev/null +++ b/CMake/ctr/FindCTRULIB.cmake @@ -0,0 +1,48 @@ +# - Try to find ctrulib +# Once done this will define +# LIBCTRU_FOUND - System has ctrulib +# LIBCTRU_INCLUDE_DIRS - The ctrulib include directories +# LIBCTRU_LIBRARIES - The libraries needed to use ctrulib +# +# It also adds an imported target named `3ds::ctrulib`. +# Linking it is the same as target_link_libraries(target ${LIBCTRU_LIBRARIES}) and target_include_directories(target ${LIBCTRU_INCLUDE_DIRS}) + +# DevkitPro paths are broken on windows, so we have to fix those +macro(msys_to_cmake_path MsysPath ResultingPath) + string(REGEX REPLACE "^/([a-zA-Z])/" "\\1:/" ${ResultingPath} "${MsysPath}") +endmacro() + +if(NOT DEVKITPRO) + msys_to_cmake_path("$ENV{DEVKITPRO}" DEVKITPRO) +endif() + +set(CTRULIB_PATHS $ENV{CTRULIB} libctru ctrulib ${DEVKITPRO}/libctru ${DEVKITPRO}/ctrulib) + +find_path(LIBCTRU_INCLUDE_DIR 3ds.h + PATHS ${CTRULIB_PATHS} + PATH_SUFFIXES include libctru/include ) + +find_library(LIBCTRU_LIBRARY NAMES ctru libctru.a + PATHS ${CTRULIB_PATHS} + PATH_SUFFIXES lib libctru/lib ) + +set(LIBCTRU_LIBRARIES ${LIBCTRU_LIBRARY} ) +set(LIBCTRU_INCLUDE_DIRS ${LIBCTRU_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set LIBCTRU_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(CTRULIB DEFAULT_MSG + LIBCTRU_LIBRARY LIBCTRU_INCLUDE_DIR) + +mark_as_advanced(LIBCTRU_INCLUDE_DIR LIBCTRU_LIBRARY ) +if(CTRULIB_FOUND) + set(CTRULIB ${LIBCTRU_INCLUDE_DIR}/..) + message(STATUS "setting CTRULIB to ${CTRULIB}") + + add_library(3ds::ctrulib STATIC IMPORTED GLOBAL) + set_target_properties(3ds::ctrulib PROPERTIES + IMPORTED_LOCATION "${LIBCTRU_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LIBCTRU_INCLUDE_DIR}" + ) +endif() diff --git a/CMake/ctr/Tools3DS.cmake b/CMake/ctr/Tools3DS.cmake new file mode 100644 index 000000000..d24f25a05 --- /dev/null +++ b/CMake/ctr/Tools3DS.cmake @@ -0,0 +1,511 @@ +############################################################################ +# Various macros for 3DS homebrews tools +# +# add_3dsx_target +# ^^^^^^^^^^^^^^^ +# +# This macro has two signatures : +# +# ## add_3dsx_target(target [NO_SMDH]) +# +# Adds a target that generates a .3dsx file from `target`. If NO_SMDH is specified, no .smdh file will be generated. +# +# You can set the following variables to change the SMDH file : +# +# * APP_TITLE is the name of the app stored in the SMDH file (Optional) +# * APP_DESCRIPTION is the description of the app stored in the SMDH file (Optional) +# * APP_AUTHOR is the author of the app stored in the SMDH file (Optional) +# * APP_ICON is the filename of the icon (.png), relative to the project folder. +# If not set, it attempts to use one of the following (in this order): +# - $(target).png +# - icon.png +# - $(libctru folder)/default_icon.png +# +# ## add_3dsx_target(target APP_TITLE APP_DESCRIPTION APP_AUTHOR [APP_ICON]) +# +# This version will produce the SMDH with tha values passed as arguments. Tha APP_ICON is optional and follows the same rule as the other version of `add_3dsx_target`. +# +# add_cia_target(target RSF IMAGE SOUND [APP_TITLE APP_DESCRIPTION APP_AUTHOR [APP_ICON]]) +# ^^^^^^^^^^^^^^ +# +# Same as add_3dsx_target but for CIA files. +# +# RSF is the .rsf file to be given to makerom. +# IMAGE is either a .png or a cgfximage file. +# SOUND is either a .wav or a cwavaudio file. +# +# add_netload_target(name target_or_file) +# ^^^^^^^^^^^^^^^^^^ +# +# Adds a target `name` that sends a .3dsx using the homebrew launcher netload system (3dslink). +# target_or_file is either the name of a target or of file. +# +# add_binary_library(target input1 [input2 ...]) +# ^^^^^^^^^^^^^^^^^^ +# +# /!\ Requires ASM to be enabled ( `enable_language(ASM)` or `project(yourprojectname C CXX ASM)`) +# +# Converts the files given as input to arrays of their binary data. This is useful to embed resources into your project. +# For example, logo.bmp will generate the array `u8 logo_bmp[]` and its size `logo_bmp_size`. By linking this library, you +# will also have access to a generated header file called `logo_bmp.h` which contains the declarations you need to use it. +# +# Note : All dots in the filename are converted to `_`, and if it starts with a number, `_` will be prepended. +# For example 8x8.gas.tex would give the name _8x8_gas_tex. +# +# target_embed_file(target input1 [input2 ...]) +# ^^^^^^^^^^^^^^^^^ +# +# Same as add_binary_library(tempbinlib input1 [input2 ...]) + target_link_libraries(target tempbinlib) +# +# add_shbin(output input [entrypoint] [shader_type]) +# ^^^^^^^^^^^^^^^^^^^^^^^ +# +# Assembles the shader given as `input` into the file `output`. No file extension is added. +# You can choose the shader assembler by setting SHADER_AS to `picasso` or `nihstro`. +# +# If `nihstro` is set as the assembler, entrypoint and shader_type will be used. +# entrypoint is set to `main` by default +# shader_type can be either VSHADER or GSHADER. By default it is VSHADER. +# +# generate_shbins(input1 [input2 ...]) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# Assemble all the shader files given as input into .shbin files. Those will be located in the folder `shaders` of the build directory. +# The names of the output files will be .shbin. vshader.pica will output shader.shbin but shader.vertex.pica will output shader.shbin too. +# +# add_shbin_library(target input1 [input2 ...]) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# /!\ Requires ASM to be enabled ( `enable_language(ASM)` or `project(yourprojectname C CXX ASM)`) +# +# This is the same as calling generate_shbins and add_binary_library. This is the function to be used to reproduce devkitArm makefiles behaviour. +# For example, add_shbin_library(shaders data/my1stshader.vsh.pica) will generate the target library `shaders` and you +# will be able to use the shbin in your program by linking it, including `my1stshader_pica.h` and using `my1stshader_pica[]` and `my1stshader_pica_size`. +# +# target_embed_shader(target input1 [input2 ...]) +# ^^^^^^^^^^^^^^^^^ +# +# Same as add_shbin_library(tempbinlib input1 [input2 ...]) + target_link_libraries(target tempbinlib) +# +############################################################################ + +if(NOT 3DS) + message(WARNING "Those tools can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +get_filename_component(__tools3dsdir ${CMAKE_CURRENT_LIST_FILE} PATH) # Used to locate files to be used with configure_file + +message(STATUS "Looking for 3ds tools...") + +############## +## 3DSXTOOL ## +############## +if(NOT _3DSXTOOL) + # message(STATUS "Looking for 3dsxtool...") + find_program(_3DSXTOOL 3dsxtool ${DEVKITARM}/bin) + if(_3DSXTOOL) + message(STATUS "3dsxtool: ${_3DSXTOOL} - found") + else() + message(WARNING "3dsxtool - not found") + endif() +endif() + + +############## +## SMDHTOOL ## +############## +if(NOT SMDHTOOL) + # message(STATUS "Looking for smdhtool...") + find_program(SMDHTOOL smdhtool ${DEVKITARM}/bin) + if(SMDHTOOL) + message(STATUS "smdhtool: ${SMDHTOOL} - found") + else() + message(WARNING "smdhtool - not found") + endif() +endif() + +################ +## BANNERTOOL ## +################ +if(NOT BANNERTOOL) + # message(STATUS "Looking for bannertool...") + find_program(BANNERTOOL bannertool ${DEVKITARM}/bin) + if(BANNERTOOL) + message(STATUS "bannertool: ${BANNERTOOL} - found") + else() + message(WARNING "bannertool - not found") + endif() +endif() + +set(FORCE_SMDHTOOL FALSE CACHE BOOL "Force the use of smdhtool instead of bannertool") + +############# +## MAKEROM ## +############# +if(NOT MAKEROM) + # message(STATUS "Looking for makerom...") + find_program(MAKEROM makerom ${DEVKITARM}/bin) + if(MAKEROM) + message(STATUS "makerom: ${MAKEROM} - found") + else() + message(WARNING "makerom - not found") + endif() +endif() + + + +############# +## STRIP ## +############# +if(NOT STRIP) + # message(STATUS "Looking for strip...") + find_program(STRIP arm-none-eabi-strip ${DEVKITARM}/bin) + if(STRIP) + message(STATUS "strip: ${STRIP} - found") + else() + message(WARNING "strip - not found") + endif() +endif() + + + +############# +## BIN2S ## +############# +if(NOT BIN2S) + # message(STATUS "Looking for bin2s...") + find_program(BIN2S bin2s ${DEVKITARM}/bin) + if(BIN2S) + message(STATUS "bin2s: ${BIN2S} - found") + else() + message(WARNING "bin2s - not found") + endif() +endif() + +############### +## 3DSLINK ## +############### +if(NOT _3DSLINK) + # message(STATUS "Looking for 3dslink...") + find_program(_3DSLINK 3dslink ${DEVKITARM}/bin) + if(_3DSLINK) + message(STATUS "3dslink: ${_3DSLINK} - found") + else() + message(WARNING "3dslink - not found") + endif() +endif() + +############# +## PICASSO ## +############# +if(NOT PICASSO_EXE) + # message(STATUS "Looking for Picasso...") + find_program(PICASSO_EXE picasso ${DEVKITARM}/bin) + if(PICASSO_EXE) + message(STATUS "Picasso: ${PICASSO_EXE} - found") + set(SHADER_AS picasso CACHE STRING "The shader assembler to be used. Allowed values are 'none', 'picasso' or 'nihstro'") + else() + message(STATUS "Picasso - not found") + endif() +endif() + + +############# +## NIHSTRO ## +############# + +if(NOT NIHSTRO_AS) + # message(STATUS "Looking for nihstro...") + find_program(NIHSTRO_AS nihstro ${DEVKITARM}/bin) + if(NIHSTRO_AS) + message(STATUS "nihstro: ${NIHSTRO_AS} - found") + set(SHADER_AS nihstro CACHE STRING "The shader assembler to be used. Allowed values are 'none', 'picasso' or 'nihstro'") + else() + message(STATUS "nihstro - not found") + endif() +endif() + +set(SHADER_AS none CACHE STRING "The shader assembler to be used. Allowed values are 'none', 'picasso' or 'nihstro'") + +############################### +############################### +######## MACROS ######### +############################### +############################### + + +################### +### EXECUTABLES ### +################### + + +function(__add_smdh target APP_TITLE APP_DESCRIPTION APP_AUTHOR APP_ICON) + if(BANNERTOOL AND NOT FORCE_SMDHTOOL) + set(__SMDH_COMMAND ${BANNERTOOL} makesmdh -s ${APP_TITLE} -l ${APP_DESCRIPTION} -p ${APP_AUTHOR} -i ${APP_ICON} -o ${CMAKE_CURRENT_BINARY_DIR}/${target}) + else() + set(__SMDH_COMMAND ${SMDHTOOL} --create ${APP_TITLE} ${APP_DESCRIPTION} ${APP_AUTHOR} ${APP_ICON} ${CMAKE_CURRENT_BINARY_DIR}/${target}) + endif() + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target} + COMMAND ${__SMDH_COMMAND} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + DEPENDS ${APP_ICON} + VERBATIM + ) +endfunction() + +function(add_3dsx_target target) + get_filename_component(target_we ${target} NAME_WE) + if((NOT (${ARGC} GREATER 1 AND "${ARGV1}" STREQUAL "NO_SMDH") ) OR (${ARGC} GREATER 3) ) + if(${ARGC} GREATER 3) + set(APP_TITLE ${ARGV1}) + set(APP_DESCRIPTION ${ARGV2}) + set(APP_AUTHOR ${ARGV3}) + endif() + if(${ARGC} EQUAL 5) + set(APP_ICON ${ARGV4}) + endif() + if(NOT APP_TITLE) + set(APP_TITLE ${target}) + endif() + if(NOT APP_DESCRIPTION) + set(APP_DESCRIPTION "Built with devkitARM & libctru") + endif() + if(NOT APP_AUTHOR) + set(APP_AUTHOR "Unspecified Author") + endif() + if(NOT APP_ICON) + if(EXISTS ${target}.png) + set(APP_ICON ${target}.png) + elseif(EXISTS icon.png) + set(APP_ICON icon.png) + elseif(CTRULIB) + set(APP_ICON ${CTRULIB}/default_icon.png) + else() + message(FATAL_ERROR "No icon found ! Please use NO_SMDH or provide some icon.") + endif() + endif() + if( NOT ${target_we}.smdh) + __add_smdh(${target_we}.smdh ${APP_TITLE} ${APP_DESCRIPTION} ${APP_AUTHOR} ${APP_ICON}) + endif() + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.3dsx + COMMAND ${_3DSXTOOL} $ ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.3dsx --smdh=${CMAKE_CURRENT_BINARY_DIR}/${target_we}.smdh + DEPENDS ${target} ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.smdh + VERBATIM + ) + else() + message(STATUS "No smdh file will be generated") + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.3dsx + COMMAND ${_3DSXTOOL} $ ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.3dsx + DEPENDS ${target} + VERBATIM + ) + endif() + add_custom_target(${target_we}_3dsx ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.3dsx) + set_target_properties(${target} PROPERTIES LINK_FLAGS "-specs=3dsx.specs") +endfunction() + +function(__add_ncch_banner target IMAGE SOUND) + if(IMAGE MATCHES ".*\\.png$") + set(IMG_PARAM -i ${IMAGE}) + else() + set(IMG_PARAM -ci ${IMAGE}) + endif() + if(SOUND MATCHES ".*\\.wav$") + set(SND_PARAM -a ${SOUND}) + else() + set(SND_PARAM -ca ${SOUND}) + endif() + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target} + COMMAND ${BANNERTOOL} makebanner -o ${CMAKE_CURRENT_BINARY_DIR}/${target} ${IMG_PARAM} ${SND_PARAM} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + DEPENDS ${IMAGE} ${SOUND} + VERBATIM + ) +endfunction() + +function(add_cia_target target RSF IMAGE SOUND ) + get_filename_component(target_we ${target} NAME_WE) + if(${ARGC} GREATER 6) + set(APP_TITLE ${ARGV4}) + set(APP_DESCRIPTION ${ARGV5}) + set(APP_AUTHOR ${ARGV6}) + endif() + if(${ARGC} EQUAL 8) + set(APP_ICON ${ARGV7}) + endif() + if(NOT APP_TITLE) + set(APP_TITLE ${target}) + endif() + if(NOT APP_DESCRIPTION) + set(APP_DESCRIPTION "Built with devkitARM & libctru") + endif() + if(NOT APP_AUTHOR) + set(APP_AUTHOR "Unspecified Author") + endif() + if(NOT APP_ICON) + if(EXISTS ${target}.png) + set(APP_ICON ${target}.png) + elseif(EXISTS icon.png) + set(APP_ICON icon.png) + elseif(CTRULIB) + set(APP_ICON ${CTRULIB}/default_icon.png) + else() + message(FATAL_ERROR "No icon found ! Please use NO_SMDH or provide some icon.") + endif() + endif() + if( NOT ${target_we}.smdh) + __add_smdh(${target_we}.smdh ${APP_TITLE} ${APP_DESCRIPTION} ${APP_AUTHOR} ${APP_ICON}) + endif() + __add_ncch_banner(${target_we}.bnr ${IMAGE} ${SOUND}) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.cia + COMMAND ${STRIP} -o $-stripped $ + COMMAND ${MAKEROM} -f cia + -target t + -exefslogo + -o ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.cia + -elf $-stripped + -rsf ${RSF} + -banner ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.bnr + -icon ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.smdh + DEPENDS ${target} ${RSF} ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.bnr ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.smdh + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + VERBATIM + ) + + add_custom_target(${target_we}_cia ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target_we}.cia) + set_target_properties(${target} PROPERTIES LINK_FLAGS "-specs=3dsx.specs") +endfunction() + +macro(add_netload_target name target) + set(NETLOAD_IP "" CACHE STRING "The ip address of the 3ds when using netload.") + if(NETLOAD_IP) + set(__NETLOAD_IP_OPTION -a ${NETLOAD_IP}) + endif() + if(NOT TARGET ${target}) + message("NOT ${target}") + set(FILE ${target}) + else() + set(FILE ${CMAKE_CURRENT_BINARY_DIR}/${target}.3dsx) + endif() + add_custom_target(${name} + COMMAND ${_3DSLINK} ${FILE} ${__NETLOAD_IP_OPTION} + DEPENDS ${FILE} + ) +endmacro() + +###################### +### File embedding ### +###################### + +macro(add_binary_library libtarget) + if(NOT ${ARGC} GREATER 1) + message(FATAL_ERROR "add_binary_library : Argument error (no input files)") + endif() + get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES) + if(NOT ENABLED_LANGUAGES MATCHES ".*ASM.*") + message(FATAL_ERROR "You have to enable ASM in order to use add_binary_library (or any target_embed_* which relies on it). Use enable_language(ASM) in your CMakeLists. Currently enabled languages are ${ENABLED_LANGUAGES}") + endif() + + + foreach(__file ${ARGN}) + get_filename_component(__file_wd ${__file} NAME) + string(REGEX REPLACE "^([0-9])" "_\\1" __BIN_FILE_NAME ${__file_wd}) # add '_' if the file name starts by a number + string(REGEX REPLACE "[-./]" "_" __BIN_FILE_NAME ${__BIN_FILE_NAME}) + + #Generate the header file + configure_file(${__tools3dsdir}/bin2s_header.h.in ${CMAKE_CURRENT_BINARY_DIR}/${libtarget}_include/${__BIN_FILE_NAME}.h) + endforeach() + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/binaries_asm) + # Generate the assembly file, and create the new target + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/binaries_asm/${libtarget}.s + COMMAND ${BIN2S} ${ARGN} > ${CMAKE_CURRENT_BINARY_DIR}/binaries_asm/${libtarget}.s + DEPENDS ${ARGN} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + ) + + add_library(${libtarget} ${CMAKE_CURRENT_BINARY_DIR}/binaries_asm/${libtarget}.s) + target_include_directories(${libtarget} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${libtarget}_include) +endmacro() + +macro(target_embed_file _target) + if(NOT ${ARGC} GREATER 1) + message(FATAL_ERROR "target_embed_file : Argument error (no input files)") + endif() + get_filename_component(__1st_file_wd ${ARGV1} NAME) + add_binary_library(__${_target}_embed_${__1st_file_wd} ${ARGN}) + target_link_libraries(${_target} __${_target}_embed_${__1st_file_wd}) +endmacro() + +################### +##### SHADERS ##### +################### + +macro(add_shbin OUTPUT INPUT ) + + if(SHADER_AS STREQUAL "picasso") + + if(${ARGC} GREATER 2) + message(WARNING "Picasso doesn't support changing the entrypoint or shader type") + endif() + add_custom_command(OUTPUT ${OUTPUT} COMMAND ${PICASSO_EXE} -o ${OUTPUT} ${INPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + + elseif(SHADER_AS STREQUAL "nihstro") + if(NOT NIHSTRO_AS) + message(SEND_ERROR "SHADER_AS is set to nihstro, but nihstro wasn't found. Please set NIHSTRO_AS.") + endif() + if(${ARGC} GREATER 2) + if(${ARGV2} EQUAL GSHADER) + set(SHADER_TYPE_FLAG "-g") + elseif(NOT ${ARGV2} EQUAL VSHADER) + set(_ENTRYPOINT ${ARGV2}) + endif() + endif() + if(${ARGC} GREATER 3) + if(${ARGV2} EQUAL GSHADER) + set(SHADER_TYPE_FLAG "-g") + elseif(NOT ${ARGV3} EQUAL VSHADER) + set(_ENTRYPOINT ${ARGV3}) + endif() + endif() + if(NOT _ENTRYPOINT) + set(_ENTRYPOINT "main") + endif() + add_custom_command(OUTPUT ${OUTPUT} COMMAND ${NIHSTRO_AS} ${INPUT} -o ${OUTPUT} -e ${_ENTRYPOINT} ${SHADER_TYPE_FLAG} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + + else() + message(FATAL_ERROR "Please set SHADER_AS to 'picasso' or 'nihstro' if you use the shbin feature.") + endif() + +endmacro() + +function(generate_shbins) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders) + foreach(__shader_file ${ARGN}) + get_filename_component(__shader_file_we ${__shader_file} NAME_WE) + #Generate the shbin file + list(APPEND __SHADERS_BIN_FILES ${CMAKE_CURRENT_BINARY_DIR}/shaders/${__shader_file_we}.shbin) + add_shbin(${CMAKE_CURRENT_BINARY_DIR}/shaders/${__shader_file_we}.shbin ${__shader_file}) + endforeach() +endfunction() + +function(add_shbin_library libtarget) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shaders) + foreach(__shader_file ${ARGN}) + get_filename_component(__shader_file_we ${__shader_file} NAME_WE) + #Generate the shbin file + list(APPEND __SHADERS_BIN_FILES ${CMAKE_CURRENT_BINARY_DIR}/shaders/${__shader_file_we}.shbin) + add_shbin(${CMAKE_CURRENT_BINARY_DIR}/shaders/${__shader_file_we}.shbin ${__shader_file}) + endforeach() + add_binary_library(${libtarget} ${__SHADERS_BIN_FILES}) +endfunction() + + +macro(target_embed_shader _target) + if(NOT ${ARGC} GREATER 1) + message(FATAL_ERROR "target_embed_shader : Argument error (no input files)") + endif() + get_filename_component(__1st_file_wd ${ARGV1} NAME) + add_shbin_library(__${_target}_embed_${__1st_file_wd} ${ARGN}) + target_link_libraries(${_target} __${_target}_embed_${__1st_file_wd}) +endmacro() diff --git a/CMake/ctr/bin2s_header.h.in b/CMake/ctr/bin2s_header.h.in new file mode 100644 index 000000000..4ea7c4cf8 --- /dev/null +++ b/CMake/ctr/bin2s_header.h.in @@ -0,0 +1,3 @@ +extern const u8 @__BIN_FILE_NAME@_end[]; +extern const u8 @__BIN_FILE_NAME@[]; +extern const u32 @__BIN_FILE_NAME@_size; diff --git a/CMake/ctr/devkitarm-libctru.cmake b/CMake/ctr/devkitarm-libctru.cmake new file mode 100644 index 000000000..8e8dee664 --- /dev/null +++ b/CMake/ctr/devkitarm-libctru.cmake @@ -0,0 +1,63 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR armv6k) +set(3DS TRUE) # To be used for multiplatform projects + +# DevkitPro Paths are broken on windows, so we have to fix those +macro(msys_to_cmake_path MsysPath ResultingPath) + if(WIN32) + string(REGEX REPLACE "^/([a-zA-Z])/" "\\1:/" ${ResultingPath} "${MsysPath}") + else() + set(${ResultingPath} "${MsysPath}") + endif() +endmacro() + +msys_to_cmake_path("$ENV{DEVKITPRO}" DEVKITPRO) +if(NOT IS_DIRECTORY ${DEVKITPRO}) + message(FATAL_ERROR "Please set DEVKITPRO in your environment") +endif() + +msys_to_cmake_path("$ENV{DEVKITARM}" DEVKITARM) +if(NOT IS_DIRECTORY ${DEVKITARM}) + message(FATAL_ERROR "Please set DEVKITARM in your environment") +endif() + +# Prefix detection only works with compiler id "GNU" +# CMake will look for prefixed g++, cpp, ld, etc. automatically +if(WIN32) + set(CMAKE_C_COMPILER "${DEVKITARM}/bin/arm-none-eabi-gcc.exe") + set(CMAKE_CXX_COMPILER "${DEVKITARM}/bin/arm-none-eabi-g++.exe") + set(CMAKE_AR "${DEVKITARM}/bin/arm-none-eabi-gcc-ar.exe" CACHE STRING "") + set(CMAKE_RANLIB "${DEVKITARM}/bin/arm-none-eabi-gcc-ranlib.exe" CACHE STRING "") +else() + set(CMAKE_C_COMPILER "${DEVKITARM}/bin/arm-none-eabi-gcc") + set(CMAKE_CXX_COMPILER "${DEVKITARM}/bin/arm-none-eabi-g++") + set(CMAKE_AR "${DEVKITARM}/bin/arm-none-eabi-gcc-ar" CACHE STRING "") + set(CMAKE_RANLIB "${DEVKITARM}/bin/arm-none-eabi-gcc-ranlib" CACHE STRING "") +endif() + +set(WITH_PORTLIBS ON CACHE BOOL "use portlibs ?") + +if(WITH_PORTLIBS) + set(CMAKE_FIND_ROOT_PATH ${DEVKITARM} ${DEVKITPRO} ${DEVKITPRO}/portlibs/3ds) +else() + set(CMAKE_FIND_ROOT_PATH ${DEVKITARM} ${DEVKITPRO}) +endif() + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +SET(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available" ) + +add_definitions(-D__3DS__ -D_3DS) + +set(ARCH "-march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ") +set(CMAKE_C_FLAGS " -mword-relocations ${ARCH}" CACHE STRING "C flags") +set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "C++ flags") +set(DKA_SUGGESTED_C_FLAGS "-fomit-frame-pointer") +set(DKA_SUGGESTED_CXX_FLAGS "${DKA_SUGGESTED_C_FLAGS} -fno-rtti -fno-exceptions -std=gnu++11") + +set(CMAKE_INSTALL_PREFIX ${DEVKITPRO}/portlibs/3ds + CACHE PATH "Install libraries in the portlibs dir") + diff --git a/CMake/ctr/modules/FindCITRO3D.cmake b/CMake/ctr/modules/FindCITRO3D.cmake new file mode 100644 index 000000000..d4d6e0ea3 --- /dev/null +++ b/CMake/ctr/modules/FindCITRO3D.cmake @@ -0,0 +1,61 @@ +# - Try to find citro3d +# You can set CITRO3D_ROOT to specify a certain directory to look in first. +# Once done this will define +# CITRO3D_FOUND - System has citro3d +# CITRO3D_INCLUDE_DIRS - The citro3d include directories +# CITRO3D_LIBRARIES - The libraries needed to use citro3d +# Unless we are unable to find CTRULIB +# It also adds an imported target named `3ds::citro3d`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${CITRO3D_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${CITRO3D_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +# citro3d requires ctrulib +libfind_package(CITRO3D CTRULIB) + +set(_CITRO3D_SEARCHES) + +# Search CITRO3D_ROOT first if it is set. +if(CITRO3D_ROOT) + set(_CITRO3D_SEARCH_ROOT + PATHS ${CITRO3D_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _CITRO3D_SEARCHES _CITRO3D_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM} etc. +set(_CITRO3D_SEARCH_NORMAL + PATHS / /citro3d /libctru /ctrulib + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _CITRO3D_SEARCHES _CITRO3D_SEARCH_NORMAL) + +foreach(search ${_CITRO3D_SEARCHES}) + find_path(CITRO3D_INCLUDE_DIR NAMES citro3d.h + ${${search}} + PATH_SUFFIXES include) + find_library(CITRO3D_LIBRARY NAMES citro3d libcitro3d.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +#find_library(LIBM_LIBRARY NAMES m libm.a +# PATHS / /arm-none-eabi +# PATH_SUFFIXES lib/armv6k/fpu) + +set(LIBM_LIBRARY m) + +set(CITRO3D_PROCESS_INCLUDES CITRO3D_INCLUDE_DIR) +set(CITRO3D_PROCESS_LIBS CITRO3D_LIBRARY LIBM_LIBRARY) + +libfind_process(CITRO3D) + +try_add_imported_target(CITRO3D m 3ds::ctrulib) diff --git a/CMake/ctr/modules/FindFreetype.cmake b/CMake/ctr/modules/FindFreetype.cmake new file mode 100644 index 000000000..2ca842347 --- /dev/null +++ b/CMake/ctr/modules/FindFreetype.cmake @@ -0,0 +1,54 @@ +# - Try to find freetype +# You can set Freetype_ROOT to specify a certain directory to look in first. +# Once done this will define +# Freetype_FOUND - System has freetype +# Freetype_INCLUDE_DIRS - The freetype include directories +# Freetype_LIBRARIES - The libraries needed to use freetype +# Unless we are unable to find ZLIB +# It also adds an imported target named `3ds::freetype`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${Freetype_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${Freetype_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +libfind_package(Freetype ZLIB) + +set(_Freetype_SEARCHES) + +# Search Freetype_ROOT first if it is set. +if(Freetype_ROOT) + set(_Freetype_SEARCH_ROOT + PATHS ${Freetype_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _Freetype_SEARCHES _Freetype_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_Freetype_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _Freetype_SEARCHES _Freetype_SEARCH_NORMAL) + +foreach(search ${_Freetype_SEARCHES}) + find_path(Freetype_INCLUDE_DIR NAMES freetype/config/ftheader.h config/ftheader.h + ${${search}} + PATH_SUFFIXES include/freetype2 include freetype2) + find_library(Freetype_LIBRARY NAMES freetype libfreetype.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +set(Freetype_PROCESS_INCLUDES Freetype_INCLUDE_DIR) +set(Freetype_PROCESS_LIBS Freetype_LIBRARY) + +libfind_process(Freetype) + +try_add_imported_target(Freetype 3ds::zlib) diff --git a/CMake/ctr/modules/FindMAD.cmake b/CMake/ctr/modules/FindMAD.cmake new file mode 100644 index 000000000..81fbe18fa --- /dev/null +++ b/CMake/ctr/modules/FindMAD.cmake @@ -0,0 +1,60 @@ +# - Try to find mad +# You can set MAD_ROOT to specify a certain directory to look in first. +# Once done this will define +# MAD_FOUND - System has mad +# MAD_INCLUDE_DIRS - The mad include directories +# MAD_LIBRARIES - The libraries needed to use mad +# Unless we are unable to find ZLIB +# It also adds an imported target named `3ds::mad`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${MAD_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${MAD_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +#libfind_package(MAD) + +set(_MAD_SEARCHES) + +# Search MAD_ROOT first if it is set. +if(MAD_ROOT) + set(_MAD_SEARCH_ROOT + PATHS ${MAD_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _MAD_SEARCHES _MAD_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_MAD_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _MAD_SEARCHES _MAD_SEARCH_NORMAL) + +foreach(search ${_MAD_SEARCHES}) + find_path(MAD_INCLUDE_DIR NAMES mad.h + ${${search}} + PATH_SUFFIXES include) + find_library(MAD_LIBRARY NAMES mad libmad.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +#find_library(LIBM_LIBRARY NAMES m libm.a +# PATHS / /arm-none-eabi +# PATH_SUFFIXES lib/armv6k/fpu) + +set(LIBM_LIBRARY m) + +set(MAD_PROCESS_INCLUDES MAD_INCLUDE_DIR) +set(MAD_PROCESS_LIBS MAD_LIBRARY LIBM_LIBRARY) + +libfind_process(MAD) + +try_add_imported_target(MAD m) diff --git a/CMake/ctr/modules/FindMikMod.cmake b/CMake/ctr/modules/FindMikMod.cmake new file mode 100644 index 000000000..3d6f09979 --- /dev/null +++ b/CMake/ctr/modules/FindMikMod.cmake @@ -0,0 +1,60 @@ +# - Try to find mikmod +# You can set MIKMOD_ROOT to specify a certain directory to look in first. +# Once done this will define +# MIKMOD_FOUND - System has mikmod +# MIKMOD_INCLUDE_DIRS - The mikmod include directories +# MIKMOD_LIBRARIES - The libraries needed to use mikmod +# Unless we are unable to find ZLIB +# It also adds an imported target named `3ds::mikmod`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${MIKMOD_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${MIKMOD_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +#libfind_package(MIKMOD) + +set(_MIKMOD_SEARCHES) + +# Search MIKMOD_ROOT first if it is set. +if(MIKMOD_ROOT) + set(_MIKMOD_SEARCH_ROOT + PATHS ${MIKMOD_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _MIKMOD_SEARCHES _MIKMOD_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_MIKMOD_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _MIKMOD_SEARCHES _MIKMOD_SEARCH_NORMAL) + +foreach(search ${_MIKMOD_SEARCHES}) + find_path(MIKMOD_INCLUDE_DIR NAMES mikmod.h + ${${search}} + PATH_SUFFIXES include) + find_library(MIKMOD_LIBRARY NAMES mikmod libmikmod.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +#find_library(LIBM_LIBRARY NAMES m libm.a +# PATHS / /arm-none-eabi +# PATH_SUFFIXES lib/armv6k/fpu) + +set(LIBM_LIBRARY m) + +set(MIKMOD_PROCESS_INCLUDES MIKMOD_INCLUDE_DIR) +set(MIKMOD_PROCESS_LIBS MIKMOD_LIBRARY LIBM_LIBRARY) + +libfind_process(MIKMOD) + +try_add_imported_target(MIKMOD m) diff --git a/CMake/ctr/modules/FindOgg.cmake b/CMake/ctr/modules/FindOgg.cmake new file mode 100644 index 000000000..dca36ad07 --- /dev/null +++ b/CMake/ctr/modules/FindOgg.cmake @@ -0,0 +1,60 @@ +# - Try to find ogg +# You can set OGG_ROOT to specify a certain directory to look in first. +# Once done this will define +# OGG_FOUND - System has ogg +# OGG_INCLUDE_DIRS - The ogg include directories +# OGG_LIBRARIES - The libraries needed to use ogg +# Unless we are unable to find ZLIB +# It also adds an imported target named `3ds::ogg`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${OGG_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${OGG_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +#libfind_package(OGG) + +set(_OGG_SEARCHES) + +# Search OGG_ROOT first if it is set. +if(OGG_ROOT) + set(_OGG_SEARCH_ROOT + PATHS ${OGG_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _OGG_SEARCHES _OGG_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_OGG_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _OGG_SEARCHES _OGG_SEARCH_NORMAL) + +foreach(search ${_OGG_SEARCHES}) + find_path(OGG_INCLUDE_DIR NAMES ogg/ogg.h + ${${search}} + PATH_SUFFIXES include) + find_library(OGG_LIBRARY NAMES ogg libogg.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +#find_library(LIBM_LIBRARY NAMES m libm.a +# PATHS / /arm-none-eabi +# PATH_SUFFIXES lib/armv6k/fpu) + +set(LIBM_LIBRARY m) + +set(OGG_PROCESS_INCLUDES OGG_INCLUDE_DIR) +set(OGG_PROCESS_LIBS OGG_LIBRARY LIBM_LIBRARY) + +libfind_process(OGG) + +try_add_imported_target(OGG m) diff --git a/CMake/ctr/modules/FindPNG.cmake b/CMake/ctr/modules/FindPNG.cmake new file mode 100644 index 000000000..acc0f3385 --- /dev/null +++ b/CMake/ctr/modules/FindPNG.cmake @@ -0,0 +1,60 @@ +# - Try to find png +# You can set PNG_ROOT to specify a certain directory to look in first. +# Once done this will define +# PNG_FOUND - System has png +# PNG_INCLUDE_DIRS - The png include directories +# PNG_LIBRARIES - The libraries needed to use png +# Unless we are unable to find ZLIB +# It also adds an imported target named `3ds::png`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${PNG_LIBRARIES}) +# target_include_directories(mytarget PRIVATE ${PNG_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +libfind_package(PNG ZLIB) + +set(_PNG_SEARCHES) + +# Search PNG_ROOT first if it is set. +if(PNG_ROOT) + set(_PNG_SEARCH_ROOT + PATHS ${PNG_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _PNG_SEARCHES _PNG_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_PNG_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _PNG_SEARCHES _PNG_SEARCH_NORMAL) + +foreach(search ${_PNG_SEARCHES}) + find_path(PNG_INCLUDE_DIR NAMES png.h + ${${search}} + PATH_SUFFIXES include) + find_library(PNG_LIBRARY NAMES png libpng.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +#find_library(LIBM_LIBRARY NAMES m libm.a +# PATHS / /arm-none-eabi +# PATH_SUFFIXES lib/armv6k/fpu) + +set(LIBM_LIBRARY m) + +set(PNG_PROCESS_INCLUDES PNG_INCLUDE_DIR) +set(PNG_PROCESS_LIBS PNG_LIBRARY LIBM_LIBRARY) + +libfind_process(PNG) + +try_add_imported_target(PNG m 3ds::zlib) diff --git a/CMake/ctr/modules/FindVorbis.cmake b/CMake/ctr/modules/FindVorbis.cmake new file mode 100644 index 000000000..15778eb9c --- /dev/null +++ b/CMake/ctr/modules/FindVorbis.cmake @@ -0,0 +1,66 @@ +# Phaethon - A FLOSS resource explorer for BioWare's Aurora engine games +# +# Phaethon is the legal property of its developers, whose names +# can be found in the AUTHORS file distributed with this source +# distribution. +# +# Phaethon is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# Phaethon is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Phaethon. If not, see . + +# Try to find vorbis library and include path. +# Once done this will define +# +# VORBIS_INCLUDE_DIRS - where to find vorbis/vorbisfile.h, etc. +# VORBIS_LIBRARIES - List of libraries when using libvorbisfile. +# VORBIS_FOUND - True if libvorbisfile found. + +if(WIN32) + find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h $ENV{PROGRAMFILES}/vorbis/include DOC "The directory where vorbis/vorbisfile.h resides") + find_library(VORBIS_LIBRARY NAMES vorbis PATHS $ENV{PROGRAMFILES}/vorbis/lib DOC "The libvorbis library") + find_library(VORBISFILE_LIBRARY NAMES vorbisfile PATHS $ENV{PROGRAMFILES}/vorbis/lib DOC "The libvorbisfile library") + +else(WIN32) + find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h DOC "The directory where vorbis/vorbisfile.h resides") + find_library(VORBIS_LIBRARY NAMES vorbis DOC "The libvorbis library") + find_library(VORBISFILE_LIBRARY NAMES vorbisfile DOC "The libvorbisfile library") + +endif(WIN32) + +if(VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY) + set(VORBIS_FOUND 1) + set(VORBIS_LIBRARIES ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY}) + set(VORBIS_INCLUDE_DIRS ${VORBIS_INCLUDE_DIR}) +else(VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY) + set(VORBIS_FOUND 0) + set(VORBIS_LIBRARIES) + set(VORBIS_INCLUDE_DIRS) +endif(VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY) + +mark_as_advanced(VORBIS_INCLUDE_DIR) +mark_as_advanced(VORBIS_LIBRARY) +mark_as_advanced(VORBISFILE_LIBRARY) +mark_as_advanced(VORBIS_FOUND) + +if(NOT VORBIS_FOUND) + set(VORBIS_DIR_MESSAGE "libvorbis and libvorbisfile were not found. Make sure VORBIS_LIBRARY, VORBISFILE_LIBRARY and VORBIS_INCLUDE_DIR are set.") + if(NOT VORBIS_FIND_QUIETLY) + message(STATUS "${VORBIS_DIR_MESSAGE}") + else(NOT VORBIS_FIND_QUIETLY) + if(VORBIS_FIND_REQUIRED) + message(FATAL_ERROR "${VORBIS_DIR_MESSAGE}") + endif(VORBIS_FIND_REQUIRED) + endif(NOT VORBIS_FIND_QUIETLY) +else(NOT VORBIS_FOUND) + message(STATUS "Found libvorbis: ${VORBIS_LIBRARY}") + message(STATUS "Found libvorbisfile: ${VORBISFILE_LIBRARY}") +endif(NOT VORBIS_FOUND) diff --git a/CMake/ctr/modules/FindZLIB.cmake b/CMake/ctr/modules/FindZLIB.cmake new file mode 100644 index 000000000..89950bcf7 --- /dev/null +++ b/CMake/ctr/modules/FindZLIB.cmake @@ -0,0 +1,51 @@ +# - Try to find zlib +# You can set ZLIB_ROOT to specify a certain directory to look in first. +# Once done this will define +# ZLIB_FOUND - System has zlib +# ZLIB_INCLUDE_DIRS - The zlib include directories +# ZLIB_LIBRARIES - The libraries needed to use zlib +# It also adds an imported target named `3ds::zlib`, Linking against it is +# equivalent to: +# target_link_libraries(mytarget ${ZLIB_LIBRARY}) +# target_include_directories(mytarget PRIVATE ${ZLIB_INCLUDE_DIRS}) + +if(NOT 3DS) + message(FATAL_ERROR "This module can only be used if you are using the 3DS toolchain file. Please erase this build directory or create another one, and then use -DCMAKE_TOOLCHAIN_FILE=DevkitArm3DS.cmake when calling cmake for the 1st time. For more information, see the Readme.md for more information.") +endif() + +include(LibFindMacros) +include(try_add_imported_target) + +set(_ZLIB_SEARCHES) + +# Search ZLIB_ROOT first if it is set. +if(ZLIB_ROOT) + set(_ZLIB_SEARCH_ROOT + PATHS ${ZLIB_ROOT} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH) + list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) +endif() + +# Search below ${DEVKITPRO}, ${DEVKITARM}, portlibs (if enabled) etc. +set(_ZLIB_SEARCH_NORMAL + PATHS / + NO_DEFAULT_PATH + ONLY_CMAKE_FIND_ROOT_PATH) +list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) + +foreach(search ${_ZLIB_SEARCHES}) + find_path(ZLIB_INCLUDE_DIR NAMES zlib.h + ${${search}} + PATH_SUFFIXES include) + find_library(ZLIB_LIBRARY NAMES z libz.a + ${${search}} + PATH_SUFFIXES lib) +endforeach() + +set(ZLIB_PROCESS_INCLUDES ZLIB_INCLUDE_DIR) +set(ZLIB_PROCESS_LIBS ZLIB_LIBRARY) + +libfind_process(ZLIB) + +try_add_imported_target(ZLIB) diff --git a/CMake/ctr/modules/LibFindMacros.cmake b/CMake/ctr/modules/LibFindMacros.cmake new file mode 100644 index 000000000..ead0f81e7 --- /dev/null +++ b/CMake/ctr/modules/LibFindMacros.cmake @@ -0,0 +1,265 @@ +# Version 2.2 +# Public Domain, originally written by Lasse Kärkkäinen +# Maintained at https://github.com/Tronic/cmake-modules +# Please send your improvements as pull requests on Github. + +# Find another package and make it a dependency of the current package. +# This also automatically forwards the "REQUIRED" argument. +# Usage: libfind_package( [extra args to find_package]) +macro (libfind_package PREFIX PKG) + set(${PREFIX}_args ${PKG} ${ARGN}) + if (${PREFIX}_FIND_REQUIRED) + set(${PREFIX}_args ${${PREFIX}_args} REQUIRED) + endif() + find_package(${${PREFIX}_args}) + set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG}) + unset(${PREFIX}_args) +endmacro() + +# A simple wrapper to make pkg-config searches a bit easier. +# Works the same as CMake's internal pkg_check_modules but is always quiet. +macro (libfind_pkg_check_modules) + find_package(PkgConfig QUIET) + if (PKG_CONFIG_FOUND) + pkg_check_modules(${ARGN} QUIET) + endif() +endmacro() + +# Avoid useless copy&pasta by doing what most simple libraries do anyway: +# pkg-config, find headers, find library. +# Usage: libfind_pkg_detect( FIND_PATH [other args] FIND_LIBRARY [other args]) +# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2) +function (libfind_pkg_detect PREFIX) + # Parse arguments + set(argname pkgargs) + foreach (i ${ARGN}) + if ("${i}" STREQUAL "FIND_PATH") + set(argname pathargs) + elseif ("${i}" STREQUAL "FIND_LIBRARY") + set(argname libraryargs) + else() + set(${argname} ${${argname}} ${i}) + endif() + endforeach() + if (NOT pkgargs) + message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.") + endif() + # Find library + libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs}) + if (pathargs) + find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS}) + endif() + if (libraryargs) + find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}) + endif() +endfunction() + +# Extracts a version #define from a version.h file, output stored to _VERSION. +# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR) +# Fourth argument "QUIET" may be used for silently testing different define names. +# This function does nothing if the version variable is already defined. +function (libfind_version_header PREFIX VERSION_H DEFINE_NAME) + # Skip processing if we already have a version or if the include dir was not found + if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR) + return() + endif() + set(quiet ${${PREFIX}_FIND_QUIETLY}) + # Process optional arguments + foreach(arg ${ARGN}) + if (arg STREQUAL "QUIET") + set(quiet TRUE) + else() + message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.") + endif() + endforeach() + # Read the header and parse for version number + set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + if (NOT EXISTS ${filename}) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + endif() + return() + endif() + file(READ "${filename}" header) + string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}") + # No regex match? + if (match STREQUAL header) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + endif() + return() + endif() + # Export the version string + set(${PREFIX}_VERSION "${match}" PARENT_SCOPE) +endfunction() + +# Do the final processing once the paths have been detected. +# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain +# all the variables, each of which contain one include directory. +# Ditto for ${PREFIX}_PROCESS_LIBS and library files. +# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. +# Also handles errors in case library detection was required, etc. +function (libfind_process PREFIX) + # Skip processing if already processed during this configuration run + if (${PREFIX}_FOUND) + return() + endif() + + set(found TRUE) # Start with the assumption that the package was found + + # Did we find any files? Did we miss includes? These are for formatting better error messages. + set(some_files FALSE) + set(missing_headers FALSE) + + # Shorthands for some variables that we need often + set(quiet ${${PREFIX}_FIND_QUIETLY}) + set(required ${${PREFIX}_FIND_REQUIRED}) + set(exactver ${${PREFIX}_FIND_VERSION_EXACT}) + set(findver "${${PREFIX}_FIND_VERSION}") + set(version "${${PREFIX}_VERSION}") + + # Lists of config option names (all, includes, libs) + unset(configopts) + set(includeopts ${${PREFIX}_PROCESS_INCLUDES}) + set(libraryopts ${${PREFIX}_PROCESS_LIBS}) + + # Process deps to add to + foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES}) + if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS) + # The package seems to export option lists that we can use, woohoo! + list(APPEND includeopts ${${i}_INCLUDE_OPTS}) + list(APPEND libraryopts ${${i}_LIBRARY_OPTS}) + else() + # If plural forms don't exist or they equal singular forms + if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR + (${i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES)) + # Singular forms can be used + if (DEFINED ${i}_INCLUDE_DIR) + list(APPEND includeopts ${i}_INCLUDE_DIR) + endif() + if (DEFINED ${i}_LIBRARY) + list(APPEND libraryopts ${i}_LIBRARY) + endif() + else() + # Oh no, we don't know the option names + message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!") + endif() + endif() + endforeach() + + if (includeopts) + list(REMOVE_DUPLICATES includeopts) + endif() + + if (libraryopts) + list(REMOVE_DUPLICATES libraryopts) + endif() + + string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}") + if (NOT tmp STREQUAL "${includeopts} ${libraryopts}") + message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).") + endif() + + # Include/library names separated by spaces (notice: not CMake lists) + unset(includes) + unset(libs) + + # Process all includes and set found false if any are missing + foreach (i ${includeopts}) + list(APPEND configopts ${i}) + if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") + list(APPEND includes "${${i}}") + else() + set(found FALSE) + set(missing_headers TRUE) + endif() + endforeach() + + # Process all libraries and set found false if any are missing + foreach (i ${libraryopts}) + list(APPEND configopts ${i}) + if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") + list(APPEND libs "${${i}}") + else() + set (found FALSE) + endif() + endforeach() + + # Version checks + if (found AND findver) + if (NOT version) + message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.") + elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver)) + set(found FALSE) + set(version_unsuitable TRUE) + endif() + endif() + + # If all-OK, hide all config options, export variables, print status and exit + if (found) + foreach (i ${configopts}) + mark_as_advanced(${i}) + endforeach() + if (NOT quiet) + message(STATUS "Found ${PREFIX} ${${PREFIX}_LIBRARY} ${${PREFIX}_VERSION}") + if (LIBFIND_DEBUG) + message(STATUS " ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}") + message(STATUS " ${PREFIX}_INCLUDE_OPTS=${includeopts}") + message(STATUS " ${PREFIX}_INCLUDE_DIRS=${includes}") + message(STATUS " ${PREFIX}_LIBRARY_OPTS=${libraryopts}") + message(STATUS " ${PREFIX}_LIBRARIES=${libs}") + endif() + endif() + set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE) + set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE) + set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE) + set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE) + set (${PREFIX}_FOUND TRUE PARENT_SCOPE) + return() + endif() + + # Format messages for debug info and the type of error + set(vars "Relevant CMake configuration variables:\n") + foreach (i ${configopts}) + mark_as_advanced(CLEAR ${i}) + set(val ${${i}}) + if ("${val}" STREQUAL "${i}-NOTFOUND") + set (val "") + elseif (val AND NOT EXISTS ${val}) + set (val "${val} (does not exist)") + else() + set(some_files TRUE) + endif() + set(vars "${vars} ${i}=${val}\n") + endforeach() + set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n") + if (version_unsuitable) + set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but") + if (exactver) + set(msg "${msg} only version ${findver} is acceptable.") + else() + set(msg "${msg} version ${findver} is the minimum requirement.") + endif() + else() + if (missing_headers) + set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?") + elseif (some_files) + set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?") + if(findver) + set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).") + endif() + else() + set(msg "We were unable to find package ${PREFIX}.") + endif() + endif() + + # Fatal error out if REQUIRED + if (required) + set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.") + message(FATAL_ERROR "${msg}\n${vars}") + endif() + # Otherwise just print a nasty warning + if (NOT quiet) + message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}") + endif() +endfunction() diff --git a/CMake/ctr/modules/try_add_imported_target.cmake b/CMake/ctr/modules/try_add_imported_target.cmake new file mode 100644 index 000000000..33e3595ef --- /dev/null +++ b/CMake/ctr/modules/try_add_imported_target.cmake @@ -0,0 +1,15 @@ +macro(try_add_imported_target LIBNAME) + string(TOLOWER ${LIBNAME} ${LIBNAME}_lwr) + set(${LIBNAME}_TARGET 3ds::${${LIBNAME}_lwr}) + if(${LIBNAME}_FOUND AND NOT TARGET ${${LIBNAME}_TARGET}) + add_library(${${LIBNAME}_TARGET} STATIC IMPORTED GLOBAL) + + set_target_properties(${${LIBNAME}_TARGET} PROPERTIES + IMPORTED_LOCATION "${${LIBNAME}_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${${LIBNAME}_INCLUDE_DIR}") + + if(${ARGC} GREATER 1) + target_link_libraries(${${LIBNAME}_TARGET} INTERFACE ${ARGN}) + endif() + endif() +endmacro() diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e90470aa..6e7c7c0a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,11 @@ if(AMIGA) include(amiga_defs) endif() +if(N3DS) + list(APPEND CMAKE_MODULE_PATH "${DevilutionX_SOURCE_DIR}/CMake/ctr") + include(n3ds_defs) +endif() + if(DIST) set(sodium_USE_STATIC_LIBS ON) endif() @@ -132,7 +137,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) +if(NOT N3DS) + find_package(Threads REQUIRED) +endif() + if(NOT NONET) find_package(sodium REQUIRED) endif() @@ -324,6 +332,16 @@ if(SWITCH) set(BIN_TARGET devilutionx.elf) endif() +if(N3DS) + list(APPEND devilutionx_SRCS + SourceX/platform/ctr/system.cpp + SourceX/platform/ctr/keyboard.cpp) +if(HELLFIRE) + set(BIN_TARGET hellfire) +endif() + set(BIN_TARGET ${BIN_TARGET}.elf) +endif() + if(RUN_TESTS) list(APPEND devilutionx_SRCS SourceT/appfat_test.cpp @@ -388,10 +406,15 @@ target_include_directories(${BIN_TARGET} PRIVATE 3rdParty/Radon/Radon/include 3rdParty/libsmacker) -target_link_libraries(devilution PUBLIC +if(N3DS) + target_link_libraries(devilution PUBLIC + SourceS) +else() + target_link_libraries(devilution PUBLIC Threads::Threads - SourceS -) + SourceS) +endif() + target_link_libraries(${BIN_TARGET} PRIVATE devilution SourceS @@ -514,6 +537,13 @@ foreach(target devilution ${BIN_TARGET} SourceS) endif() endif() + if(N3DS) + target_link_libraries(${target} PRIVATE ${TREMOR_LIBRARIES}) + target_include_directories(${target} PRIVATE ${TREMOR_INCLUDE_DIRS}) + target_link_libraries(${target} PRIVATE 3ds::ogg 3ds::mikmod 3ds::mad 3ds::freetype 3ds::bzip2 3ds::png) + target_link_libraries(${target} PRIVATE 3ds::citro3d 3ds::ctrulib) + endif() + target_compile_definitions(${target} PRIVATE ${def_list}) endforeach(target) @@ -614,6 +644,31 @@ if(SWITCH) build_switch_binaries(${BIN_TARGET}) endif() +if(N3DS) + set(APP_TITLE "DevilutionX") + set(APP_DESCRIPTION "DevilutionX port for 3DS") + set(APP_AUTHOR "Diasurgical Team") + set(APP_ICON "${PROJECT_SOURCE_DIR}/Packaging/ctr/icon.png") + set(APP_BANNER "${PROJECT_SOURCE_DIR}/Packaging/ctr/banner.png") + set(APP_AUDIO "${PROJECT_SOURCE_DIR}/Packaging/ctr/audio_silent.wav") + set(APP_RSF "${PROJECT_SOURCE_DIR}/Packaging/ctr/template.rsf") + set(APP_ROMFS "${CMAKE_BINARY_DIR}/romfs") + set(APP_ROMFS_FILES "${PROJECT_SOURCE_DIR}/Packaging/ctr/DiabloLight.ttf") + if(HELLFIRE) + set(APP_TITLE "DevilutionX: Hellfire") + set(APP_ICON "${PROJECT_SOURCE_DIR}/Packaging/ctr/icon_hellfire.png") + set(APP_BANNER "${PROJECT_SOURCE_DIR}/Packaging/ctr/banner_hellfire.png") + set(APP_RSF "${PROJECT_SOURCE_DIR}/Packaging/ctr/template_hellfire.rsf") + endif() + file(MAKE_DIRECTORY ${APP_ROMFS}) + file(COPY ${APP_ROMFS_FILES} + DESTINATION ${APP_ROMFS}) + set(APP_VERSION ${PROJECT_VERSION}) + include(Tools3DS) + add_3dsx_target(${BIN_TARGET}) + add_cia_target(${BIN_TARGET} ${APP_RSF} ${APP_BANNER} ${APP_AUDIO} ${APP_ROMFS}) +endif() + if(CPACK) if(NOT SYSTEM_BITS MATCHES x64 AND WIN32) set(CPACK_PACKAGE_FILE_NAME "devilutionx") diff --git a/Packaging/ctr/build.sh b/Packaging/ctr/build.sh new file mode 100644 index 000000000..bbfd9c584 --- /dev/null +++ b/Packaging/ctr/build.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -euo pipefail + +DEVKITPRO="${DEVKITPRO:-/opt/devkitpro}" + +declare -r DIR="$(dirname "${BASH_SOURCE[0]}")" +cd "$DIR" + +main() { + prepare_devkitpro + set -x + install_deps + build +} + +build() { + mkdir -p ../../build + cd ../../build + rm -f CMakeCache.txt + DEVKITPRO="$DEVKITPRO" cmake .. -DBINARY_RELEASE=ON -DUSE_SDL1=ON -DNONET=ON \ + -DSDL1_VIDEO_MODE_FLAGS='SDL_SWSURFACE|SDL_CONSOLEBOTTOM' \ + -DCMAKE_TOOLCHAIN_FILE=../CMake/ctr/devkitarm-libctru.cmake + DEVKITPRO="$DEVKITPRO" make -j "$(nproc)" + cd - +} + +install_deps() { + "$DEVKITPRO/pacman/bin/pacman" -S --needed --noconfirm --quiet \ + 3ds-sdl 3ds-sdl_ttf 3ds-sdl_mixer \ + 3ds-freetype 3ds-libvorbis 3ds-libmikmod\ + libctru devkitARM general-tools 3ds-tools devkitpro-pkgbuild-helpers +} + +prepare_devkitpro() { + if [[ -d $DEVKITPRO ]]; then + return; + fi + if which dpkg > /dev/null; then + install_devkitpro_debian + else + >&2 printf "Please set DEVKITPRO:\nhttps://devkitpro.org/wiki/Getting_Started\n" + exit 1 + fi +} + +install_devkitpro_debian() { + >&2 echo 'Installing devkitpro-pacman.deb from GitHub...' + local -r dpkg_path=/tmp/devkitpro-pacman.deb + set -x + \curl -L https://github.com/devkitPro/pacman/releases/download/devkitpro-pacman-1.0.1/devkitpro-pacman.deb -o "$dpkg_path" + sudo dpkg -i "$dpkg_path" + rm "$dpkg_path" + { set +x; } 2>/dev/null +} + +main diff --git a/README.md b/README.md index b054dfe91..d25a106fd 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,37 @@ The nro-file will be generated in the build folder. Test with an emulator (RyuJi [Nintendo Switch manual](docs/manual/platforms/switch.md) +
Nintendo 3DS + +### Installing dependencies + +https://devkitpro.org/wiki/Getting_Started + + +- Install (dkp-)pacman: https://devkitpro.org/wiki/devkitPro_pacman + +- Install required packages with (dkp-)pacman: +``` +sudo (dkp-)pacman -S devkitARM general-tools 3dstools devkitpro-pkgbuild-helpers \ + libctru citro3d 3ds-sdl 3ds-sdl_ttf 3ds-sdl_mixer \ + 3ds-freetype 3ds-libogg 3ds-libvorbisidec 3ds-mikmod +``` +- Download or compile [bannertool](https://github.com/Steveice10/bannertool/releases) and [makerom](https://github.com/jakcron/Project_CTR/releases) + - Copy binaries to: `/opt/devkitpro/tools/bin/` + +### Compiling +``` +cd build +cmake .. -DNIGHTLY_BUILD=ON -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/3ds.cmake +make -j$(nproc) +``` +*Note:* Add `-DHELLFIRE=ON` to build the Hellfire binaries. + +The output-files will be generated in the build folder. + +[Nintendo 3DS manual](docs/manual/platforms/n3ds.md) +
+
Haiku ### Installing dependencies on 32 bit Haiku