From d345189b6896a80add9766cc5ce418d5fccd5ac8 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 13 Oct 2019 02:54:50 +0100 Subject: [PATCH] switch-next: Build with CMake (#334) * Update CMake/Findsodium.cmake from upstream * CMake/Findsodium.cmake: Support "Generic" platform Allows it work using the Switch toolchain * Switch port: Code changes for latest devkitpro * switch/build.sh: Fewer devkitpro packages --- .circleci/config.yml | 10 +- 3rdParty/StormLib/src/StormPort.h | 3 +- CMake/Findsodium.cmake | 585 ++++++++++++++--------------- CMake/switch/FindLIBNX.cmake | 44 +++ CMake/switch/devkita64-libnx.cmake | 46 +++ CMake/switch/nx-utils.cmake | 186 +++++++++ CMake/switch/utils.cmake | 17 + CMakeLists.txt | 65 +++- Packaging/switch/build.sh | 60 +++ switch/switch_keyboard.cpp | 158 ++++---- switch/switch_keyboard.h | 12 +- 11 files changed, 790 insertions(+), 396 deletions(-) create mode 100644 CMake/switch/FindLIBNX.cmake create mode 100644 CMake/switch/devkita64-libnx.cmake create mode 100644 CMake/switch/nx-utils.cmake create mode 100644 CMake/switch/utils.cmake create mode 100755 Packaging/switch/build.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index b1718d7a7337..12f2c4db576b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,8 +64,14 @@ jobs: working_directory: ~/repo steps: - checkout - - run: make -j$(nproc) - - store_artifacts: {path: ./release/devilutionx.nro, destination: devilutionx.nro} + - run: echo deb http://deb.debian.org/debian stretch-backports main > /etc/apt/sources.list.d/debian-backports.list + - run: apt-get update && apt-get install -y -t stretch-backports cmake + # Install cmake files (https://github.com/devkitPro/docker/issues/3) + - run: dkp-pacman -S --needed --noconfirm --quiet devkitpro-pkgbuild-helpers + # NOTE: Doesn't link without LTO ("read-only segment has dynamic relocations"). + - run: cd build && cmake .. -DBINARY_RELEASE=ON -DNONET=ON -DCMAKE_TOOLCHAIN_FILE=../CMake/switch/devkita64-libnx.cmake + - run: cd build && cmake --build . -j $(nproc) + - store_artifacts: {path: ./build/devilutionx.nro, destination: devilutionx.nro} workflows: version: 2 diff --git a/3rdParty/StormLib/src/StormPort.h b/3rdParty/StormLib/src/StormPort.h index 49712d140dfd..79c57e8190ff 100644 --- a/3rdParty/StormLib/src/StormPort.h +++ b/3rdParty/StormLib/src/StormPort.h @@ -161,6 +161,7 @@ #include #include #include + #include #include #include #include @@ -276,7 +277,7 @@ #endif // !PLATFORM_WINDOWS // 64-bit calls are supplied by "normal" calls on Mac -#if defined(PLATFORM_MAC) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) || defined(PLATFORM_NX) +#if defined(PLATFORM_MAC) || defined(PLATFORM_HAIKU) || defined(PLATFORM_AMIGA) || defined(PLATFORM_SWITCH) #define stat64 stat #define fstat64 fstat #define lseek64 lseek diff --git a/CMake/Findsodium.cmake b/CMake/Findsodium.cmake index c664ccbe3dbe..0edd9bfe2cde 100644 --- a/CMake/Findsodium.cmake +++ b/CMake/Findsodium.cmake @@ -1,294 +1,291 @@ -# Written in 2016 by Henrik Steffen Gaßmann -# -# To the extent possible under law, the author(s) have dedicated all -# copyright and related and neighboring rights to this software to the -# public domain worldwide. This software is distributed without any warranty. -# -# You should have received a copy of the CC0 Public Domain Dedication -# along with this software. If not, see -# -# http://creativecommons.org/publicdomain/zero/1.0/ -# -######################################################################## -# Tries to find the local libsodium installation. -# -# On Windows the sodium_DIR environment variable is used as a default -# hint which can be overridden by setting the corresponding cmake variable. -# -# Once done the following variables will be defined: -# -# sodium_FOUND -# sodium_INCLUDE_DIR -# sodium_LIBRARY_DEBUG -# sodium_LIBRARY_RELEASE -# -# -# Furthermore an imported "sodium" target is created. -# - -if (CMAKE_C_COMPILER_ID STREQUAL "GNU" - OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(_GCC_COMPATIBLE 1) -endif() - -# static library option -if (NOT DEFINED sodium_USE_STATIC_LIBS) - option(sodium_USE_STATIC_LIBS "enable to statically link against sodium" OFF) -endif() -if(NOT (sodium_USE_STATIC_LIBS EQUAL sodium_USE_STATIC_LIBS_LAST)) - unset(sodium_LIBRARY CACHE) - unset(sodium_LIBRARY_DEBUG CACHE) - unset(sodium_LIBRARY_RELEASE CACHE) - unset(sodium_DLL_DEBUG CACHE) - unset(sodium_DLL_RELEASE CACHE) - set(sodium_USE_STATIC_LIBS_LAST ${sodium_USE_STATIC_LIBS} CACHE INTERNAL "internal change tracking variable") -endif() - - -######################################################################## -# UNIX -if (UNIX) - # import pkg-config - find_package(PkgConfig QUIET) - if (PKG_CONFIG_FOUND) - pkg_check_modules(sodium_PKG QUIET libsodium) - endif() - - if(sodium_USE_STATIC_LIBS) - foreach(_libname ${sodium_PKG_STATIC_LIBRARIES}) - if (NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending with .a - list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a") - endif() - endforeach() - list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES) - - # if pkgconfig for libsodium doesn't provide - # static lib info, then override PKG_STATIC here.. - if (NOT sodium_PKG_STATIC_FOUND) - set(sodium_PKG_STATIC_LIBRARIES libsodium.a) - endif() - - set(XPREFIX sodium_PKG_STATIC) - else() - if (NOT sodium_PKG_FOUND) - set(sodium_PKG_LIBRARIES sodium) - endif() - - set(XPREFIX sodium_PKG) - endif() - - find_path(sodium_INCLUDE_DIR sodium.h - HINTS ${${XPREFIX}_INCLUDE_DIRS} - ) - find_library(sodium_LIBRARY_DEBUG NAMES ${${XPREFIX}_LIBRARIES} - HINTS ${${XPREFIX}_LIBRARY_DIRS} - ) - find_library(sodium_LIBRARY_RELEASE NAMES ${${XPREFIX}_LIBRARIES} - HINTS ${${XPREFIX}_LIBRARY_DIRS} - ) - - -######################################################################## -# Windows -elseif (WIN32) - set(sodium_DIR "$ENV{sodium_DIR}" CACHE FILEPATH "sodium install directory") - mark_as_advanced(sodium_DIR) - - find_path(sodium_INCLUDE_DIR sodium.h - HINTS ${sodium_DIR} - PATH_SUFFIXES include - ) - - if (MSVC) - # detect target architecture - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.cpp" [=[ - #if defined _M_IX86 - #error ARCH_VALUE x86_32 - #elif defined _M_X64 - #error ARCH_VALUE x86_64 - #endif - #error ARCH_VALUE unknown - ]=]) - try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/arch.cpp" - OUTPUT_VARIABLE _COMPILATION_LOG - ) - string(REGEX REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*" "\\1" _TARGET_ARCH "${_COMPILATION_LOG}") - - # construct library path - if (_TARGET_ARCH STREQUAL "x86_32") - string(APPEND _PLATFORM_PATH "Win32") - elseif(_TARGET_ARCH STREQUAL "x86_64") - string(APPEND _PLATFORM_PATH "x64") - else() - message(FATAL_ERROR "the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake.") - endif() - string(APPEND _PLATFORM_PATH "/$$CONFIG$$") - - if (MSVC_VERSION LESS 1900) - math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60") - else() - math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50") - endif() - string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}") - - if (sodium_USE_STATIC_LIBS) - string(APPEND _PLATFORM_PATH "/static") - else() - string(APPEND _PLATFORM_PATH "/dynamic") - endif() - - string(REPLACE "$$CONFIG$$" "Debug" _DEBUG_PATH_SUFFIX "${_PLATFORM_PATH}") - string(REPLACE "$$CONFIG$$" "Release" _RELEASE_PATH_SUFFIX "${_PLATFORM_PATH}") - - find_library(sodium_LIBRARY_DEBUG libsodium.lib - HINTS ${sodium_DIR} - PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX} - ) - find_library(sodium_LIBRARY_RELEASE libsodium.lib - HINTS ${sodium_DIR} - PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX} - ) - if (NOT sodium_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") - find_library(sodium_DLL_DEBUG libsodium - HINTS ${sodium_DIR} - PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX} - ) - find_library(sodium_DLL_RELEASE libsodium - HINTS ${sodium_DIR} - PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX} - ) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK}) - endif() - - elseif(_GCC_COMPATIBLE) - if (sodium_USE_STATIC_LIBS) - find_library(sodium_LIBRARY_DEBUG libsodium.a - HINTS ${sodium_DIR} - PATH_SUFFIXES lib - ) - find_library(sodium_LIBRARY_RELEASE libsodium.a - HINTS ${sodium_DIR} - PATH_SUFFIXES lib - ) - else() - find_library(sodium_LIBRARY_DEBUG libsodium.dll.a - HINTS ${sodium_DIR} - PATH_SUFFIXES lib - ) - find_library(sodium_LIBRARY_RELEASE libsodium.dll.a - HINTS ${sodium_DIR} - PATH_SUFFIXES lib - ) - - file(GLOB _DLL - LIST_DIRECTORIES false - RELATIVE "${sodium_DIR}/bin" - "${sodium_DIR}/bin/libsodium*.dll" - ) - find_library(sodium_DLL_DEBUG ${_DLL} libsodium - HINTS ${sodium_DIR} - PATH_SUFFIXES bin - ) - find_library(sodium_DLL_RELEASE ${_DLL} libsodium - HINTS ${sodium_DIR} - PATH_SUFFIXES bin - ) - endif() - else() - message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") - endif() - - -######################################################################## -# unsupported -else() - message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") -endif() - - -######################################################################## -# common stuff - -# extract sodium version -if (sodium_INCLUDE_DIR) - set(_VERSION_HEADER "${_INCLUDE_DIR}/sodium/version.h") - if (EXISTS _VERSION_HEADER) - file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT) - string(REGEX REPLACE ".*#[ \t]*define[ \t]*SODIUM_VERSION_STRING[ \t]*\"([^\n]*)\".*" "\\1" - sodium_VERSION "${_VERSION_HEADER_CONTENT}") - set(sodium_VERSION "${sodium_VERSION}" PARENT_SCOPE) - endif() -endif() - -# communicate results -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Sodium # The name must be either uppercase or match the filename case. - REQUIRED_VARS - sodium_LIBRARY_RELEASE - sodium_LIBRARY_DEBUG - sodium_INCLUDE_DIR - VERSION_VAR - sodium_VERSION -) - -if(Sodium_FOUND) - set(sodium_LIBRARIES - optimized ${sodium_LIBRARY_RELEASE} debug ${sodium_LIBRARY_DEBUG}) -endif() - -# mark file paths as advanced -mark_as_advanced(sodium_INCLUDE_DIR) -mark_as_advanced(sodium_LIBRARY_DEBUG) -mark_as_advanced(sodium_LIBRARY_RELEASE) -if (WIN32) - mark_as_advanced(sodium_DLL_DEBUG) - mark_as_advanced(sodium_DLL_RELEASE) -endif() - -# create imported target -if(sodium_USE_STATIC_LIBS) - set(_LIB_TYPE STATIC) -else() - set(_LIB_TYPE SHARED) -endif() -add_library(sodium ${_LIB_TYPE} IMPORTED) - -set_target_properties(sodium PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${sodium_INCLUDE_DIR}" - IMPORTED_LINK_INTERFACE_LANGUAGES "C" -) - -if (sodium_USE_STATIC_LIBS) - set_target_properties(sodium PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "SODIUM_STATIC" - IMPORTED_LOCATION "${sodium_LIBRARY_RELEASE}" - IMPORTED_LOCATION_DEBUG "${sodium_LIBRARY_DEBUG}" - ) -else() - if (UNIX) - set_target_properties(sodium PROPERTIES - IMPORTED_LOCATION "${sodium_LIBRARY_RELEASE}" - IMPORTED_LOCATION_DEBUG "${sodium_LIBRARY_DEBUG}" - ) - elseif (WIN32) - set_target_properties(sodium PROPERTIES - IMPORTED_IMPLIB "${sodium_LIBRARY_RELEASE}" - IMPORTED_IMPLIB_DEBUG "${sodium_LIBRARY_DEBUG}" - ) - if (NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND")) - set_target_properties(sodium PROPERTIES - IMPORTED_LOCATION_DEBUG "${sodium_DLL_DEBUG}" - ) - endif() - if (NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND")) - set_target_properties(sodium PROPERTIES - IMPORTED_LOCATION_RELWITHDEBINFO "${sodium_DLL_RELEASE}" - IMPORTED_LOCATION_MINSIZEREL "${sodium_DLL_RELEASE}" - IMPORTED_LOCATION_RELEASE "${sodium_DLL_RELEASE}" - ) - endif() - endif() -endif() +# Written in 2016 by Henrik Steffen Gaßmann +# +# To the extent possible under law, the author(s) have dedicated all copyright +# and related and neighboring rights to this software to the public domain +# worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication along with +# this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +# ############################################################################## +# Tries to find the local libsodium installation. +# +# On Windows the sodium_DIR environment variable is used as a default hint which +# can be overridden by setting the corresponding cmake variable. +# +# Once done the following variables will be defined: +# +# sodium_FOUND sodium_INCLUDE_DIR sodium_LIBRARY_DEBUG sodium_LIBRARY_RELEASE +# sodium_VERSION_STRING +# +# Furthermore an imported "sodium" target is created. +# + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(_GCC_COMPATIBLE 1) +endif() + +# static library option +if(NOT DEFINED sodium_USE_STATIC_LIBS) + option(sodium_USE_STATIC_LIBS "enable to statically link against sodium" OFF) +endif() +if(NOT (sodium_USE_STATIC_LIBS EQUAL sodium_USE_STATIC_LIBS_LAST)) + unset(sodium_LIBRARY CACHE) + unset(sodium_LIBRARY_DEBUG CACHE) + unset(sodium_LIBRARY_RELEASE CACHE) + unset(sodium_DLL_DEBUG CACHE) + unset(sodium_DLL_RELEASE CACHE) + set(sodium_USE_STATIC_LIBS_LAST + ${sodium_USE_STATIC_LIBS} + CACHE INTERNAL "internal change tracking variable") +endif() + +# ############################################################################## +# UNIX +if(UNIX OR CMAKE_SYSTEM_NAME STREQUAL "Generic") + # import pkg-config + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_check_modules(sodium_PKG QUIET libsodium) + endif() + + if(sodium_USE_STATIC_LIBS) + if(sodium_PKG_STATIC_LIBRARIES) + foreach(_libname ${sodium_PKG_STATIC_LIBRARIES}) + if(NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending + # with .a + list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a") + endif() + endforeach() + list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES) + else() + # if pkgconfig for libsodium doesn't provide static lib info, then + # override PKG_STATIC here.. + set(sodium_PKG_STATIC_LIBRARIES libsodium.a) + endif() + + set(XPREFIX sodium_PKG_STATIC) + else() + if(sodium_PKG_LIBRARIES STREQUAL "") + set(sodium_PKG_LIBRARIES sodium) + endif() + + set(XPREFIX sodium_PKG) + endif() + + find_path(sodium_INCLUDE_DIR sodium.h HINTS ${${XPREFIX}_INCLUDE_DIRS}) + find_library(sodium_LIBRARY_DEBUG + NAMES ${${XPREFIX}_LIBRARIES} + HINTS ${${XPREFIX}_LIBRARY_DIRS}) + find_library(sodium_LIBRARY_RELEASE + NAMES ${${XPREFIX}_LIBRARIES} + HINTS ${${XPREFIX}_LIBRARY_DIRS}) + + # ############################################################################ + # Windows +elseif(WIN32) + set(sodium_DIR "$ENV{sodium_DIR}" CACHE FILEPATH "sodium install directory") + mark_as_advanced(sodium_DIR) + + find_path(sodium_INCLUDE_DIR sodium.h + HINTS ${sodium_DIR} + PATH_SUFFIXES include) + + if(MSVC) + # detect target architecture + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.c" [=[ + #if defined _M_IX86 + #error ARCH_VALUE x86_32 + #elif defined _M_X64 + #error ARCH_VALUE x86_64 + #endif + #error ARCH_VALUE unknown + ]=]) + try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/arch.c" + OUTPUT_VARIABLE _COMPILATION_LOG) + string(REGEX + REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*" + "\\1" + _TARGET_ARCH + "${_COMPILATION_LOG}") + + # construct library path + if(_TARGET_ARCH STREQUAL "x86_32") + string(APPEND _PLATFORM_PATH "Win32") + elseif(_TARGET_ARCH STREQUAL "x86_64") + string(APPEND _PLATFORM_PATH "x64") + else() + message( + FATAL_ERROR + "the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake." + ) + endif() + string(APPEND _PLATFORM_PATH "/$$CONFIG$$") + + if(MSVC_VERSION LESS 1900) + math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60") + else() + math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50") + endif() + string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}") + + if(sodium_USE_STATIC_LIBS) + string(APPEND _PLATFORM_PATH "/static") + else() + string(APPEND _PLATFORM_PATH "/dynamic") + endif() + + string(REPLACE "$$CONFIG$$" + "Debug" + _DEBUG_PATH_SUFFIX + "${_PLATFORM_PATH}") + string(REPLACE "$$CONFIG$$" + "Release" + _RELEASE_PATH_SUFFIX + "${_PLATFORM_PATH}") + + find_library(sodium_LIBRARY_DEBUG libsodium.lib + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}) + find_library(sodium_LIBRARY_RELEASE libsodium.lib + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}) + if(NOT sodium_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") + find_library(sodium_DLL_DEBUG libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}) + find_library(sodium_DLL_RELEASE libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK}) + endif() + + elseif(_GCC_COMPATIBLE) + if(sodium_USE_STATIC_LIBS) + find_library(sodium_LIBRARY_DEBUG libsodium.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + find_library(sodium_LIBRARY_RELEASE libsodium.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + else() + find_library(sodium_LIBRARY_DEBUG libsodium.dll.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + find_library(sodium_LIBRARY_RELEASE libsodium.dll.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + + file(GLOB _DLL + LIST_DIRECTORIES false + RELATIVE "${sodium_DIR}/bin" + "${sodium_DIR}/bin/libsodium*.dll") + find_library(sodium_DLL_DEBUG ${_DLL} libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES bin) + find_library(sodium_DLL_RELEASE ${_DLL} libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES bin) + endif() + else() + message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") + endif() + + # ############################################################################ + # unsupported +else() + message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") +endif() + +# ############################################################################## +# common stuff + +# extract sodium version +if(sodium_INCLUDE_DIR) + set(_VERSION_HEADER "${sodium_INCLUDE_DIR}/sodium/version.h") + if(EXISTS "${_VERSION_HEADER}") + file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT) + string(REGEX + REPLACE ".*define[ \t]+SODIUM_VERSION_STRING[^\"]+\"([^\"]+)\".*" + "\\1" + sodium_VERSION_STRING + "${_VERSION_HEADER_CONTENT}") + set(sodium_VERSION_STRING "${sodium_VERSION_STRING}") + endif() +endif() + +# communicate results +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(sodium + REQUIRED_VARS + sodium_LIBRARY_RELEASE + sodium_LIBRARY_DEBUG + sodium_INCLUDE_DIR + VERSION_VAR + sodium_VERSION_STRING) + +# mark file paths as advanced +mark_as_advanced(sodium_INCLUDE_DIR) +mark_as_advanced(sodium_LIBRARY_DEBUG) +mark_as_advanced(sodium_LIBRARY_RELEASE) +if(WIN32) + mark_as_advanced(sodium_DLL_DEBUG) + mark_as_advanced(sodium_DLL_RELEASE) +endif() + +# create imported target +if(sodium_USE_STATIC_LIBS) + set(_LIB_TYPE STATIC) +else() + set(_LIB_TYPE SHARED) +endif() +add_library(sodium ${_LIB_TYPE} IMPORTED) + +set_target_properties(sodium + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${sodium_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES + "C") + +if(sodium_USE_STATIC_LIBS) + set_target_properties(sodium + PROPERTIES INTERFACE_COMPILE_DEFINITIONS + "SODIUM_STATIC" + IMPORTED_LOCATION + "${sodium_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG + "${sodium_LIBRARY_DEBUG}") +else() + if(UNIX) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION + "${sodium_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG + "${sodium_LIBRARY_DEBUG}") + elseif(WIN32) + set_target_properties(sodium + PROPERTIES IMPORTED_IMPLIB + "${sodium_LIBRARY_RELEASE}" + IMPORTED_IMPLIB_DEBUG + "${sodium_LIBRARY_DEBUG}") + if(NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND")) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION_DEBUG + "${sodium_DLL_DEBUG}") + endif() + if(NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND")) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO + "${sodium_DLL_RELEASE}" + IMPORTED_LOCATION_MINSIZEREL + "${sodium_DLL_RELEASE}" + IMPORTED_LOCATION_RELEASE + "${sodium_DLL_RELEASE}") + endif() + endif() +endif() diff --git a/CMake/switch/FindLIBNX.cmake b/CMake/switch/FindLIBNX.cmake new file mode 100644 index 000000000000..4ea27295562d --- /dev/null +++ b/CMake/switch/FindLIBNX.cmake @@ -0,0 +1,44 @@ +# https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/cmake/FindLIBNX.cmake + +# Tries to find libnx +# Once done, this will define: +# > LIBNX_FOUND - The system has libnx +# > LIBNX_INCLUDE_DIRS - The libnx include directories +# > LIBNX_LIBRARIES - The libnx libraries required for using it +# +# It also adds an imported target named `switch::libnx`. + +include(utils) # <- devilutionX patch + +if (NOT SWITCH) + cmake_panic("This helper can only be used if you are using the Switch toolchain file.") +endif () + +set(LIBNX_PATHS $ENV{LIBNX} libnx ${LIBNX} ${DEVKITPRO}/libnx) + +find_path(LIBNX_INCLUDE_DIR switch.h + PATHS ${LIBNX_PATHS} + PATH_SUFFIXES include) + +find_library(LIBNX_LIBRARY NAMES libnx.a + PATHS ${LIBNX_PATHS} + PATH_SUFFIXES lib) + +set(LIBNX_INCLUDE_DIRS ${LIBNX_INCLUDE_DIR}) +set(LIBNX_LIBRARIES ${LIBNX_LIBRARY}) + +# Handle the QUIETLY and REQUIRED arguments and set LIBNX_FOUND to TRUE if all above variables are TRUE. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LIBNX DEFAULT_MSG + LIBNX_INCLUDE_DIR LIBNX_LIBRARY) + +mark_as_advanced(LIBNX_INCLUDE_DIR LIBNX_LIBRARY) +if (LIBNX_FOUND) + set(LIBNX ${LIBNX_INCLUDE_DIR}/..) + cmake_info("Setting LIBNX to ${LIBNX}") + + add_library(switch::libnx STATIC IMPORTED GLOBAL) + set_target_properties(switch::libnx PROPERTIES + IMPORTED_LOCATION ${LIBNX_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES ${LIBNX_INCLUDE_DIR}) +endif () diff --git a/CMake/switch/devkita64-libnx.cmake b/CMake/switch/devkita64-libnx.cmake new file mode 100644 index 000000000000..125f50dc7547 --- /dev/null +++ b/CMake/switch/devkita64-libnx.cmake @@ -0,0 +1,46 @@ +if(NOT DEFINED ENV{DEVKITPRO}) + message(FATAL_ERROR "Please set the DEVKITPRO env var to ") +endif() + +# devkitPro paths are broken on Windows. We need to use this macro to fix those. +# from https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/devkita64-libnx.cmake +macro(msys_to_cmake_path msys_path resulting_path) + if (WIN32) + string(REGEX REPLACE "^/([a-zA-Z])/" "\\1:/" ${resulting_path} ${msys_path}) + else () + set(${resulting_path} ${msys_path}) + endif () +endmacro() +msys_to_cmake_path($ENV{DEVKITPRO} DEVKITPRO) + +# Default devkitpro cmake +include(${DEVKITPRO}/switch.cmake) + +# Set root paths: +set(DEVKITA64 ${DEVKITPRO}/devkitA64) +set(LIBNX ${DEVKITPRO}/libnx) +set(PORTLIBS_PATH ${DEVKITPRO}/portlibs) +set(PORTLIBS ${PORTLIBS_PATH}/switch) +set(CMAKE_FIND_ROOT_PATH ${DEVKITA64} ${LIBNX} ${PORTLIBS}) + +# Set absolute tool paths: +set(TOOLCHAIN_PREFIX ${DEVKITA64}/bin/aarch64-none-elf-) +if(WIN32) + set(TOOLCHAIN_SUFFIX ".exe") +else() + set(TOOLCHAIN_SUFFIX "") +endif() +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++${TOOLCHAIN_SUFFIX}) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}as${TOOLCHAIN_SUFFIX}) +set(PKG_CONFIG_EXECUTABLE ${TOOLCHAIN_PREFIX}pkg-config${TOOLCHAIN_SUFFIX}) +set(CMAKE_AR ${TOOLCHAIN_PREFIX}gcc-ar${TOOLCHAIN_SUFFIX} CACHE STRING "") +set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}gcc-ranlib${TOOLCHAIN_SUFFIX} CACHE STRING "") +set(CMAKE_LD "/${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "") +set(CMAKE_OBJCOPY "${TOOLCHAIN_PREFIX}objcopy${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "") +set(CMAKE_SIZE_UTIL "${TOOLCHAIN_PREFIX}size${TOOLCHAIN_SUFFIX}" CACHE INTERNAL "") + +set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available") + +set(SWITCH ON) # To be used for multiplatform projects +add_definitions(-D__SWITCH__ -DSWITCH -D_POSIX_C_SOURCE=200809L) diff --git a/CMake/switch/nx-utils.cmake b/CMake/switch/nx-utils.cmake new file mode 100644 index 000000000000..d82754a02e6b --- /dev/null +++ b/CMake/switch/nx-utils.cmake @@ -0,0 +1,186 @@ +# https://github.com/vbe0201/libnx-template/blob/5283aabad32789675542ef98dad9c91838a3e729/cmake/nx-utils.cmake + +if (NOT SWITCH) + cmake_panic("These utils can only be used if you are using the Switch toolchain file.") +endif () + +############# +## ELF2NRO ## +############# +if (NOT ELF2NRO) + find_program(ELF2NRO elf2nro ${DEVKITPRO}/tools/bin) + if (ELF2NRO) + cmake_info("elf2nro: ${ELF2NRO} - found") + else () + cmake_warning("elf2nro - not found") + endif () +endif () + +############# +## ELF2KIP ## +############# +if (NOT ELF2KIP) + find_program(ELF2KIP elf2kip ${DEVKITPRO}/tools/bin) + if (ELF2KIP) + cmake_info("elf2kip: ${ELF2KIP} - found") + else () + cmake_warning("elf2kip - not found") + endif () +endif () + +############# +## ELF2NSO ## +############# +if (NOT ELF2NSO) + find_program(ELF2NSO elf2nso ${DEVKITPRO}/tools/bin) + if (ELF2NSO) + cmake_info("elf2nso: ${ELF2NSO} - found") + else () + cmake_warning("elf2nso - not found") + endif () +endif () + +############# +## BIN2S ## +############# +if (NOT BIN2S) + find_program(BIN2S bin2s ${DEVKITPRO}/tools/bin) + if (BIN2S) + cmake_info("bin2s: ${BIN2S} - found") + else () + cmake_warning("bin2s - not found") + endif () +endif () + +############# +## RAW2C ## +############# +if (NOT RAW2C) + find_program(RAW2C raw2c ${DEVKITPRO}/tools/bin) + if (RAW2C) + cmake_info("raw2c: ${RAW2C} - found") + else () + cmake_warning("raw2c - not found") + endif () +endif () + +################## +## BUILD_PFS0 ## +################## +if (NOT BUILD_PFS0) + find_program(BUILD_PFS0 build_pfs0 ${DEVKITPRO}/tools/bin) + if (BUILD_PFS0) + cmake_info("build_pfs0: ${BUILD_PFS0} - found") + else () + cmake_warning("build_pfs0 - not found") + endif () +endif () + +################ +## NACPTOOL ## +################ +if (NOT NACPTOOL) + find_program(NACPTOOL nacptool ${DEVKITPRO}/tools/bin) + if (NACPTOOL) + cmake_info("nacptool: ${NACPTOOL} - found") + else () + cmake_warning("nacptool - not found") + endif () +endif () + +macro(acquire_homebrew_icon target) + # This basically imitates the behavior of the Makefiles + # from the switchbrew/switch-examples repository. + if (EXISTS ${target}.jpg) + set(APP_ICON ${target}.jpg) + elseif (EXISTS ${PROJECT_SOURCE_DIR}/assets/icon.jpg) + set(APP_ICON ${PROJECT_SOURCE_DIR}/assets/icon.jpg) + elseif (LIBNX) + set(APP_ICON ${LIBNX}/default_icon.jpg) + else () + cmake_panic("No icon found, please provide one!") + endif () +endmacro() + +function(add_nso_target target) + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso + COMMAND ${ELF2NSO} ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso + DEPENDS ${target}.elf + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + VERBATIM) + + if (CMAKE_RUNTIME_OUTPUT_DIRECTORY) + add_custom_target(${target}.nso ALL SOURCES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}.nso) + else () + add_custom_target(${target}.nso ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target}.nso) + endif () +endfunction() + +function(add_nacp target) + set(__NACP_COMMAND ${NACPTOOL} --create ${APP_TITLE} ${APP_AUTHOR} ${APP_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/${target}) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target} + COMMAND ${__NACP_COMMAND} + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + VERBATIM) +endfunction() + +function(add_nro_target target) + set(__NRO_COMMAND + ${ELF2NRO} $ ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro --nacp=${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp --icon=${APP_ICON}) + + if (NOT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp) + add_nacp(${target}.nacp) + endif () + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro + COMMAND ${__NRO_COMMAND} + DEPENDS ${target}.elf ${CMAKE_CURRENT_BINARY_DIR}/${target}.nacp + VERBATIM) + + if (CMAKE_RUNTIME_OUTPUT_DIRECTORY) + add_custom_target(${target}.nro ALL SOURCES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}.nro) + else () + add_custom_target(${target}.nro ALL SOURCES ${CMAKE_CURRENT_BINARY_DIR}/${target}.nro) + endif () +endfunction() + +function(build_switch_binaries target) + get_filename_component(target_we ${target} NAME_WE) + + if (NOT APP_TITLE) + if (${ARGC} GREATER 1) + set(APP_TITLE ${ARGV1}) + else () + set(APP_TITLE ${target_we}) + endif () + endif () + + if (NOT APP_AUTHOR) + if (${ARGC} GREATER 2) + set(APP_AUTHOR ${ARGV2}) + else () + set(APP_AUTHOR "Unspecified Author") + endif () + endif () + + if (NOT APP_ICON) + if (${ARGC} GREATER 4) + set(APP_ICON ${ARGV4}) + else () + acquire_homebrew_icon(${target_we}) + endif () + endif () + + if (NOT APP_VERSION) + if (${ARGC} GREATER 3) + set(APP_VERSION ${ARGV3}) + else () + set(APP_VERSION "1.0.0") + endif () + endif () + + # Build the binaries + add_nso_target(${target_we}) + add_nro_target(${target_we}) +endfunction() diff --git a/CMake/switch/utils.cmake b/CMake/switch/utils.cmake new file mode 100644 index 000000000000..3042595864a7 --- /dev/null +++ b/CMake/switch/utils.cmake @@ -0,0 +1,17 @@ +# https://github.com/switchpy/libnx-template/blob/7037982c77e1767410143103d5963d0ddc77fb64/cmake/utils.cmake + +function(cmake_info message) + if (cmake_VERBOSE) + message("Build-Info: ${message}") + endif () +endfunction() + +function(cmake_warning message) + if (cmake_VERBOSE) + message(WARNING "${message}") + endif () +endfunction() + +function(cmake_panic message) + message(FATAL_ERROR "${message}") +endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c1b9021be09..8e69ff7ea961 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.10) # CMP0083 NEW include(CMake/out_of_tree.cmake) @@ -9,6 +9,7 @@ endif() option(ASAN "Enable address sanitizer" ON) option(UBSAN "Enable undefined behaviour sanitizer" ON) option(DEBUG "Enable debug mode in engine" ON) +option(PIE "Generate position-independent code" OFF) option(LTO "Enable link-time optimization (if supported by the toolchain)" OFF) option(SPAWN "Build the shareware version" OFF) option(DIST "Dynamically link only glibc and SDL2" OFF) @@ -62,6 +63,15 @@ endif() list(APPEND CMAKE_MODULE_PATH "${DevilutionX_SOURCE_DIR}/CMake") +if(SWITCH) + set(ASAN OFF) + set(UBSAN OFF) + set(PIE ON) + + list(APPEND CMAKE_MODULE_PATH "${DevilutionX_SOURCE_DIR}/CMake/switch") + find_package(LIBNX REQUIRED) +endif() + if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD OR ${CMAKE_SYSTEM_NAME} STREQUAL OpenBSD) set(ASAN OFF) set(UBSAN OFF) @@ -83,6 +93,10 @@ if(DIST OR DINGUX) set(sodium_USE_STATIC_LIBS ON) endif() +if(PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +endif() + set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -265,18 +279,25 @@ if(NOT NONET) SourceX/dvlnet/udp_p2p.cpp) endif() -add_executable(devilutionx MACOSX_BUNDLE ${devilutionx_SRCS}) +set(BIN_TARGET devilutionx) + +if(SWITCH) + list(APPEND devilutionx_SRCS switch/switch_keyboard.cpp) + set(BIN_TARGET devilutionx.elf) +endif() + +add_executable(${BIN_TARGET} MACOSX_BUNDLE ${devilutionx_SRCS}) configure_file(SourceS/config.h.in config.h @ONLY) target_include_directories(devilution PUBLIC Source SourceS ${CMAKE_CURRENT_BINARY_DIR}) -target_include_directories(devilutionx PRIVATE +target_include_directories(${BIN_TARGET} PRIVATE SourceX 3rdParty/asio/include 3rdParty/Radon/Radon/include 3rdParty/libsmacker) target_link_libraries(devilution PUBLIC Threads::Threads) -target_link_libraries(devilutionx PRIVATE +target_link_libraries(${BIN_TARGET} PRIVATE devilution PKWare StormLib @@ -284,7 +305,7 @@ target_link_libraries(devilutionx PRIVATE Radon) if(NOT NONET) - target_link_libraries(devilutionx PRIVATE sodium) + target_link_libraries(${BIN_TARGET} PRIVATE sodium) endif() target_compile_definitions(devilution PRIVATE DEVILUTION_ENGINE) @@ -292,7 +313,7 @@ target_compile_definitions(devilution PUBLIC "$<$:_DEBUG>" # Skip fades and other fluff "$<$:FASTER>") -target_compile_definitions(devilutionx PRIVATE ASIO_STANDALONE) +target_compile_definitions(${BIN_TARGET} PRIVATE ASIO_STANDALONE) # Defines without value foreach( @@ -380,6 +401,13 @@ foreach(target devilution devilutionx) target_link_libraries(${target} PUBLIC -fsanitize=undefined) endif() + if(SWITCH) + target_compile_definitions(${target} PRIVATE SWITCH) + target_link_libraries(${target} PRIVATE switch::libnx + # Most of these shouldn't be necessary. + -lfreetype -lvorbisfile -lvorbis -logg -lmodplug -lmikmod -lmpg123 -lSDL2 -lopusfile -lopus -lEGL -lglapi -ldrm_nouveau -lpng -lbz2 -lz -lnx) + endif() + target_compile_definitions(${target} PRIVATE ${def_list}) endforeach(target) @@ -388,7 +416,7 @@ if(DIST AND CMAKE_CXX_COMPILER_ID MATCHES "GNU") endif() if(WIN32) - target_link_libraries(devilutionx PRIVATE wsock32 ws2_32 wininet) + target_link_libraries(${BIN_TARGET} PRIVATE wsock32 ws2_32 wininet) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") target_compile_options(devilution PUBLIC $<$:-gstabs>) @@ -401,7 +429,7 @@ if(NOT WIN32 AND NOT APPLE) endif() if(HAIKU) - target_link_libraries(devilutionx PRIVATE network) + target_link_libraries(${BIN_TARGET} PRIVATE network) endif() if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") @@ -422,7 +450,7 @@ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # For ARM and other default unsigned char platforms target_compile_options(devilution PRIVATE -fsigned-char) - target_compile_options(devilutionx PRIVATE -fsigned-char) + target_compile_options(${BIN_TARGET} PRIVATE -fsigned-char) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") @@ -431,9 +459,9 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Style issues - target_compile_options(devilutionx PRIVATE -Wno-parentheses -Wno-logical-op-parentheses -Wno-bitwise-op-parentheses) + target_compile_options(${BIN_TARGET} PRIVATE -Wno-parentheses -Wno-logical-op-parentheses -Wno-bitwise-op-parentheses) # Silence warnings about __int64 alignment hack not always being applicable - target_compile_options(devilutionx PRIVATE -Wno-ignored-attributes) + target_compile_options(${BIN_TARGET} PRIVATE -Wno-ignored-attributes) # Silence appfat.cpp warnings set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing") endif() @@ -448,10 +476,10 @@ if(APPLE) set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) set(MACOSX_BUNDLE_LONG_VERSION_STRING "Version ${PROJECT_VERSION}") - set_target_properties(devilutionx PROPERTIES MACOSX_BUNDLE_ICON_FILE "AppIcon") - set_target_properties(devilutionx PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Packaging/macOS/Info.plist") + set_target_properties(${BIN_TARGET} PROPERTIES MACOSX_BUNDLE_ICON_FILE "AppIcon") + set_target_properties(${BIN_TARGET} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Packaging/macOS/Info.plist") - install (TARGETS devilutionx DESTINATION ./) + install (TARGETS ${BIN_TARGET} DESTINATION ./) if(DIST) install(CODE " @@ -469,6 +497,15 @@ if(APPLE) include(CPack) endif() +if(SWITCH) + set(APP_TITLE "DevilutionX") + set(APP_AUTHOR "Devilution Team") + set(APP_ICON "${PROJECT_SOURCE_DIR}/switch/icon.jpg") + set(APP_VERSION ${PROJECT_VERSION}) + include(nx-utils) + build_switch_binaries(${BIN_TARGET}) +endif() + if(DINGUX) set_target_properties(devilutionx PROPERTIES OUTPUT_NAME "devilutionx.dge") endif() diff --git a/Packaging/switch/build.sh b/Packaging/switch/build.sh new file mode 100755 index 000000000000..aac90964f8b2 --- /dev/null +++ b/Packaging/switch/build.sh @@ -0,0 +1,60 @@ +#!/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 -DNONET=ON \ + -DCMAKE_TOOLCHAIN_FILE=../CMake/switch/devkita64-libnx.cmake + DEVKITPRO="$DEVKITPRO" make -j "$(nproc)" + cd - +} + +package() { + ./package.sh ../../build/devilutionx-opendingux-musl-sdl1.ipk +} + +install_deps() { + "$DEVKITPRO/pacman/bin/pacman" -S --needed --noconfirm --quiet \ + switch-freetype switch-mesa switch-glad switch-glm switch-sdl2 \ + switch-sdl2_ttf switch-sdl2_mixer switch-libvorbis switch-libmikmod switch-libsodium \ + libnx devkitA64 devkitA64 general-tools switch-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/switch/switch_keyboard.cpp b/switch/switch_keyboard.cpp index 8b8b46b2dcba..13a65cf325c3 100644 --- a/switch/switch_keyboard.cpp +++ b/switch/switch_keyboard.cpp @@ -1,79 +1,79 @@ -#include -#include - -#include -#include -#include "switch_keyboard.h" - -static void switch_keyboard_get(char *guide_text, char *initial_text, int max_len, int multiline, char *buf) -{ - Result rc = 0; - - SwkbdConfig kbd; - - rc = swkbdCreate(&kbd, 0); - - if (R_SUCCEEDED(rc)) { - swkbdConfigMakePresetDefault(&kbd); - swkbdConfigSetGuideText(&kbd, guide_text); - swkbdConfigSetInitialText(&kbd, initial_text); - swkbdConfigSetStringLenMax(&kbd, max_len); - rc = swkbdShow(&kbd, buf, max_len); - swkbdClose(&kbd); - } -} - -static int get_utf8_character_bytes(const uint8_t *uc) -{ - if (uc[0] < 0x80) { - return 1; - } else if ((uc[0] & 0xe0) == 0xc0 && (uc[1] & 0xc0) == 0x80) { - return 2; - } else if ((uc[0] & 0xf0) == 0xe0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80) { - return 3; - } else if ((uc[0] & 0xf8) == 0xf0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80 && (uc[3] & 0xc0) == 0x80) { - return 4; - } else { - return 1; - } -} - -static void switch_create_and_push_sdlkey_event(uint32_t event_type, SDL_Scancode scan, SDL_Keycode key) -{ - SDL_Event event; - event.type = event_type; - event.key.keysym.scancode = scan; - event.key.keysym.sym = key; - event.key.keysym.mod = 0; - SDL_PushEvent(&event); -} - -void switch_start_text_input(char *guide_text, char *initial_text, int multiline) -{ - char text[65] = {'\0'}; - switch_keyboard_get(guide_text, initial_text, 64, multiline, text); - for (int i = 0; i < 600; i++) { - switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE); - switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE); - } - for (int i = 0; i < 600; i++) { - switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_DELETE, SDLK_DELETE); - switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_DELETE, SDLK_DELETE); - } - if (text[0] == '\0') { - strncpy(text, initial_text, 63); - text[64] = {'\0'}; - } - const uint8_t *utf8_text = (uint8_t*) text; - for (int i = 0; i < 599 && utf8_text[i];) { - int bytes_in_char = get_utf8_character_bytes(&utf8_text[i]); - SDL_Event textinput_event; - textinput_event.type = SDL_TEXTINPUT; - for (int n = 0; n < bytes_in_char; n++) { - textinput_event.text.text[n] = text[i + n]; - } - textinput_event.text.text[bytes_in_char] = 0; - SDL_PushEvent(&textinput_event); - i += bytes_in_char; - } -} +#include +#include + +#include +#include +#include "switch_keyboard.h" + +static void switch_keyboard_get(const char *guide_text, char *initial_text, int max_len, int multiline, char *buf) +{ + Result rc = 0; + + SwkbdConfig kbd; + + rc = swkbdCreate(&kbd, 0); + + if (R_SUCCEEDED(rc)) { + swkbdConfigMakePresetDefault(&kbd); + swkbdConfigSetGuideText(&kbd, guide_text); + swkbdConfigSetInitialText(&kbd, initial_text); + swkbdConfigSetStringLenMax(&kbd, max_len); + rc = swkbdShow(&kbd, buf, max_len); + swkbdClose(&kbd); + } +} + +static int get_utf8_character_bytes(const uint8_t *uc) +{ + if (uc[0] < 0x80) { + return 1; + } else if ((uc[0] & 0xe0) == 0xc0 && (uc[1] & 0xc0) == 0x80) { + return 2; + } else if ((uc[0] & 0xf0) == 0xe0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80) { + return 3; + } else if ((uc[0] & 0xf8) == 0xf0 && (uc[1] & 0xc0) == 0x80 && (uc[2] & 0xc0) == 0x80 && (uc[3] & 0xc0) == 0x80) { + return 4; + } else { + return 1; + } +} + +static void switch_create_and_push_sdlkey_event(uint32_t event_type, SDL_Scancode scan, SDL_Keycode key) +{ + SDL_Event event; + event.type = event_type; + event.key.keysym.scancode = scan; + event.key.keysym.sym = key; + event.key.keysym.mod = 0; + SDL_PushEvent(&event); +} + +void switch_start_text_input(const char *guide_text, char *initial_text, int multiline) +{ + char text[65] = {'\0'}; + switch_keyboard_get(guide_text, initial_text, 64, multiline, text); + for (int i = 0; i < 600; i++) { + switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE); + switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_BACKSPACE, SDLK_BACKSPACE); + } + for (int i = 0; i < 600; i++) { + switch_create_and_push_sdlkey_event(SDL_KEYDOWN, SDL_SCANCODE_DELETE, SDLK_DELETE); + switch_create_and_push_sdlkey_event(SDL_KEYUP, SDL_SCANCODE_DELETE, SDLK_DELETE); + } + if (text[0] == '\0') { + strncpy(text, initial_text, 63); + text[64] = {'\0'}; + } + const uint8_t *utf8_text = (uint8_t*) text; + for (int i = 0; i < 599 && utf8_text[i];) { + int bytes_in_char = get_utf8_character_bytes(&utf8_text[i]); + SDL_Event textinput_event; + textinput_event.type = SDL_TEXTINPUT; + for (int n = 0; n < bytes_in_char; n++) { + textinput_event.text.text[n] = text[i + n]; + } + textinput_event.text.text[bytes_in_char] = 0; + SDL_PushEvent(&textinput_event); + i += bytes_in_char; + } +} diff --git a/switch/switch_keyboard.h b/switch/switch_keyboard.h index 78ac2f8dd9dc..220b6e84d8dc 100644 --- a/switch/switch_keyboard.h +++ b/switch/switch_keyboard.h @@ -1,6 +1,6 @@ -#ifndef SWITCH_KEYBOARD_H -#define SWITCH_KEYBOARD_H - -void switch_start_text_input(char *guide_text, char *initial_text, int multiline); - -#endif /* SWITCH_KEYBOARD_H */ +#ifndef SWITCH_KEYBOARD_H +#define SWITCH_KEYBOARD_H + +void switch_start_text_input(const char *guide_text, char *initial_text, int multiline); + +#endif /* SWITCH_KEYBOARD_H */