├── .gitignore ├── LICENSE.md ├── README.md ├── cmake ├── Modules │ ├── Bin2s.cmake │ ├── Bincat.cmake │ ├── FileSplit.cmake │ ├── FindFreeImage.cmake │ ├── Findagbabi.cmake │ ├── Findbutano.cmake │ ├── Findgba-hpp.cmake │ ├── Findgbfs.cmake │ ├── Findgbt-player.cmake │ ├── Findgrit.cmake │ ├── Findlibgba.cmake │ ├── Findlibmultiboot.cmake │ ├── Findlibrom.cmake │ ├── Findlibseven.cmake │ ├── Findmaxmod.cmake │ ├── Findposprintf.cmake │ ├── Findsuperfamiconv.cmake │ ├── Findtonclib.cmake │ ├── Findxilefianlib.cmake │ ├── GbaFix.cmake │ ├── Hexdecode.cmake │ ├── IHex.cmake │ └── Mktemp.cmake ├── Platform │ ├── AdvancedGameBoy-Clang-C.cmake │ ├── AdvancedGameBoy-Clang-CXX.cmake │ ├── AdvancedGameBoy-GNU-C.cmake │ ├── AdvancedGameBoy-GNU-CXX.cmake │ └── AdvancedGameBoy.cmake ├── SuperFamiconv.cmake └── gba.toolchain.cmake └── lib ├── multiboot ├── CMakeLists.txt ├── crt0.s ├── multiboot.header.s ├── multiboot.ld └── syscalls.c └── rom ├── CMakeLists.txt ├── crt0.s ├── rom.header.s ├── rom.ld └── syscalls.c /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /devel/ 3 | /lib/gbfs/ 4 | /lib/libseven/ 5 | /lib/maxmod/ 6 | /lib/posprintf/ 7 | /lib/superfamiconv/ 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | gba-toolchain is available under the [zlib license](https://www.zlib.net/zlib_license.html) : 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gba-toolchain 2 | 3 | # Requirements 4 | 5 | * [CMake](https://cmake.org/) (3.18 minimum) 6 | * Arm compiler toolchain ([Arm GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads), [devkitPro](https://devkitpro.org/)) 7 | 8 | # Basic usage 9 | 10 | gba-toolchain provides a CMake toolchain file "`cmake/gba.toolchain.cmake`" that sets up compilers & tools for GBA development. 11 | 12 | For more information on CMake toolchains see: [cmake-toolchains cross-compiling](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling) 13 | 14 | ## Command line 15 | 16 | CMake toolchains can be used with CMake on the command line as such: 17 | 18 | ```shell 19 | cmake -S . -B build --toolchain=/path/to/cmake/gba.toolchain.cmake 20 | ``` 21 | 22 | Or for CMake versions prior to `3.21`: 23 | 24 | ```shell 25 | cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=/path/to/cmake/gba.toolchain.cmake 26 | ``` 27 | 28 | ## CMake presets file 29 | 30 | For more information on CMake presets files see: [cmake-presets configure-preset](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) 31 | 32 | Objects of `configurePresets` has the member `toolchainFile`: 33 | 34 | ```json 35 | { 36 | "version": 3, 37 | "cmakeMinimumRequired": { 38 | "major": 3, 39 | "minor": 21, 40 | "patch": 0 41 | }, 42 | "configurePresets": [ 43 | { 44 | "name": "gba-toolchain", 45 | "generator": "Unix Makefiles", 46 | "toolchainFile": "/path/to/cmake/gba.toolchain.cmake" 47 | } 48 | ] 49 | } 50 | ``` 51 | 52 | # Example CMakeLists.txt 53 | 54 | ```cmake 55 | cmake_minimum_required(VERSION 3.18) 56 | project(my_project LANGUAGES C) 57 | 58 | add_executable(my_executable main.c) 59 | 60 | # gba-toolchain sets `CMAKE_SYSTEM_NAME` to `AdvancedGameBoy` 61 | if(CMAKE_SYSTEM_NAME STREQUAL AdvancedGameBoy) 62 | find_package(librom REQUIRED) # ROM runtime 63 | find_package(libseven REQUIRED) # C development library 64 | find_package(agbabi REQUIRED) # Optimized library functions 65 | 66 | target_compile_options(my_executable PRIVATE -mthumb -fconserve-stack -fomit-frame-pointer) 67 | target_link_libraries(my_executable PRIVATE librom libseven agbabi) 68 | 69 | # ROM header info 70 | set_target_properties(my_executable PROPERTIES 71 | ROM_TITLE "My Game" 72 | ROM_ID AABE 73 | ROM_MAKER CD 74 | ROM_VERSION 1 75 | ) 76 | 77 | # install to .gba 78 | install_rom(my_executable) 79 | endif() 80 | ``` 81 | 82 | # CMake modules 83 | 84 | CMake modules are made available with the `find_package` function. 85 | 86 | For more information on CMake `find_package` see: [cmake-commands find_package](https://cmake.org/cmake/help/latest/command/find_package.html) 87 | 88 | | Package | Module | Description | Additional CMake functions | 89 | |---------------|-------------------------|--------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------| 90 | | librom | Findlibrom.cmake | ROM runtime library for standard .gba ROMs | | 91 | | libmultiboot | Findlibmultiboot.cmake | Multiboot runtime library for executables transferred via GBA MultiBoot | | 92 | | gba-hpp | Findgba-hpp.cmake | C++20 GBA development library ([more info](https://github.com/felixjones/gba-hpp)) | | 93 | | libseven | Findlibseven.cmake | Modern C GBA development library from sdk-seven ([more info](https://github.com/LunarLambda/sdk-seven)) | | 94 | | libgba | Findlibgba.cmake | C GBA development library from devkitPro ([more info](https://github.com/devkitPro/libgba)) | | 95 | | tonclib | Findtonclib.cmake | Classic C GBA development library from Coranac ([more info](https://www.coranac.com/man/tonclib/main.htm)) | | 96 | | gbfs | Findgbfs.cmake | Archive format for the GBA ([more info](https://pineight.com/gba/#gbfs)) | `add_gbfs_archive` | 97 | | maxmod | Findmaxmod.cmake | GBA music and sound solution ([more info](https://maxmod.devkitpro.org/)) | `add_maxmod_soundbank` | 98 | | superfamiconv | Findsuperfamiconv.cmake | Tile graphics converter ([more info](https://github.com/Optiroc/SuperFamiconv)) | `add_superfamiconv_graphics` | 99 | | agbabi | Findagbabi.cmake | Library functions optimized for the GBA ([more info](https://github.com/felixjones/agbabi)) | | 100 | | posprintf | Findposprintf.cmake | Partial implementation of `sprintf` optimized for the GBA ([more info](http://www.danposluns.com/gbadev/posprintf/index.html)) | | 101 | | grit | Findgrit.cmake | Bitmap and Tile graphics converter ([more info](https://www.coranac.com/man/grit/html/grit.htm)) | `add_grit_bitmap`
`add_grit_sprite`
`add_grit_tilemap` | 102 | | butano | Findbutano.cmake | Butano engine ([more info](https://github.com/GValiente/butano)) | `add_butano_assets` | 103 | | gbt-player | Findgbt-player.cmake | Game Boy music player library and converter kit ([more info](https://github.com/AntonioND/gbt-player)) | `add_gbt_assets`
`add_gbt_maxmod_assets` | | 104 | 105 | **Important**: Some modules may have external dependencies that may require tools to be compiled with a host compiler. 106 | -------------------------------------------------------------------------------- /cmake/Modules/Bin2s.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(BIN2S_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(bin2s output) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${BIN2S_SCRIPT}" -- "${ARGN}" 14 | OUTPUT_VARIABLE outputVariable OUTPUT_STRIP_TRAILING_WHITESPACE 15 | ) 16 | set("${output}" "${outputVariable}" PARENT_SCOPE) 17 | endfunction() 18 | return() 19 | endif() 20 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 21 | 22 | # Collect arguments past -- into CMAKE_ARGN 23 | foreach(ii RANGE ${CMAKE_ARGC}) 24 | if(${ii} EQUAL ${CMAKE_ARGC}) 25 | break() 26 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 27 | set(start ${ii}) 28 | elseif(DEFINED start) 29 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 30 | endif() 31 | endforeach() 32 | unset(start) 33 | 34 | # Script begin 35 | 36 | function(split var size) 37 | string(LENGTH ${${var}} len) 38 | 39 | set(chunks) 40 | foreach(ii RANGE 0 ${len} ${size}) 41 | string(SUBSTRING ${${var}} ${ii} ${size} chunk) 42 | list(APPEND chunks ${chunk}) 43 | endforeach () 44 | 45 | set(${var} ${chunks} PARENT_SCOPE) 46 | endfunction() 47 | 48 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "/* Generated by Bin2s.cmake */") 49 | 50 | foreach(arg ${CMAKE_ARGN}) 51 | file(READ "${arg}" data HEX) 52 | string(LENGTH ${data} size) 53 | split(data 32) 54 | 55 | get_filename_component(arg "${arg}" NAME) 56 | string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" arg "${arg}") 57 | 58 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo_append " .section .rodata.${arg}, \"a\" 59 | .balign 60 | .global ${arg} 61 | ${arg}: 62 | ") 63 | 64 | foreach(line ${data}) 65 | split(line 2) 66 | list(TRANSFORM line PREPEND "0x") 67 | list(JOIN line ", " line) 68 | 69 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo_append ".byte ${line} 70 | ") 71 | endforeach() 72 | 73 | math(EXPR size "${size} / 2") 74 | 75 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo_append " 76 | .global ${arg}_end 77 | ${arg}_end: 78 | 79 | .global ${arg}_size 80 | .balign 4 81 | ${arg}_size: .int ${size} 82 | ") 83 | endforeach() 84 | -------------------------------------------------------------------------------- /cmake/Modules/Bincat.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(BINCAT_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(bincat infile output boundary) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${BINCAT_SCRIPT}" -- "${infile}" "${output}" ${boundary} "${ARGN}" 14 | ) 15 | endfunction() 16 | return() 17 | endif() 18 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 19 | 20 | # Collect arguments past -- into CMAKE_ARGN 21 | foreach(ii RANGE ${CMAKE_ARGC}) 22 | if(${ii} EQUAL ${CMAKE_ARGC}) 23 | break() 24 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 25 | set(start ${ii}) 26 | elseif(DEFINED start) 27 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 28 | endif() 29 | endforeach() 30 | unset(start) 31 | 32 | # Script begin 33 | 34 | cmake_policy(PUSH) 35 | cmake_policy(SET CMP0007 NEW) 36 | 37 | list(LENGTH CMAKE_ARGN argc) 38 | if(${argc} LESS 3) 39 | message(FATAL_ERROR "Bincat requires input file, boundary, and output file.") 40 | endif() 41 | list(POP_FRONT CMAKE_ARGN input) # First arg is input 42 | list(POP_FRONT CMAKE_ARGN output) # Second arg is output 43 | list(POP_FRONT CMAKE_ARGN boundary) # Third arg is boundary 44 | 45 | cmake_policy(POP) 46 | 47 | # Check boundary 48 | math(EXPR boundary "${boundary}") 49 | if(${boundary} LESS_EQUAL 1) 50 | # Just need to cat into output 51 | execute_process( 52 | COMMAND "${CMAKE_COMMAND}" -E cat "${input}" ${CMAKE_ARGN} 53 | OUTPUT_FILE "${output}" 54 | ) 55 | return() 56 | endif() 57 | 58 | # Setup (output will act as an accumulator) 59 | file(COPY_FILE "${input}" "${output}") 60 | 61 | include("${CMAKE_CURRENT_LIST_DIR}/Mktemp.cmake") 62 | include("${CMAKE_CURRENT_LIST_DIR}/Hexdecode.cmake") 63 | 64 | foreach(file ${CMAKE_ARGN}) 65 | # Calculate padding length 66 | file(SIZE "${output}" filesize) 67 | 68 | # Pad output 69 | math(EXPR paddingLength "${filesize} % ${boundary}") 70 | if(paddingLength) 71 | math(EXPR paddingLength "${boundary} - ${paddingLength}") 72 | 73 | # Write padding bytes 74 | string(REPEAT 00 ${paddingLength} paddingHexes) 75 | mktemp(tmphex) 76 | hexdecode("${tmphex}" "${paddingHexes}") 77 | 78 | # Concat padding bytes 79 | mktemp(tmppad) 80 | execute_process( 81 | COMMAND "${CMAKE_COMMAND}" -E cat "${output}" "${tmphex}" 82 | OUTPUT_FILE "${tmppad}" 83 | ) 84 | file(REMOVE "${tmphex}") 85 | file(REMOVE "${output}") 86 | file(RENAME "${tmppad}" "${output}") 87 | endif() 88 | 89 | # Append file 90 | mktemp(tmpcat) 91 | execute_process( 92 | COMMAND "${CMAKE_COMMAND}" -E cat "${output}" "${file}" 93 | OUTPUT_FILE "${tmpcat}" 94 | ) 95 | file(REMOVE "${output}") 96 | file(RENAME "${tmpcat}" "${output}") 97 | endforeach() 98 | -------------------------------------------------------------------------------- /cmake/Modules/FileSplit.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(FILESPLIT_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(file_split infile) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${FILESPLIT_SCRIPT}" -- "${infile}" "${ARGN}" 14 | ) 15 | endfunction() 16 | return() 17 | endif() 18 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 19 | 20 | # Collect arguments past -- into CMAKE_ARGN 21 | foreach(ii RANGE ${CMAKE_ARGC}) 22 | if(${ii} EQUAL ${CMAKE_ARGC}) 23 | break() 24 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 25 | set(start ${ii}) 26 | elseif(DEFINED start) 27 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 28 | endif() 29 | endforeach() 30 | unset(start) 31 | 32 | # Script begin 33 | 34 | cmake_policy(PUSH) 35 | cmake_policy(SET CMP0007 NEW) 36 | 37 | if(NOT CMAKE_ARGN) 38 | message(FATAL_ERROR "FileSplit requires input file.") 39 | endif() 40 | list(POP_FRONT CMAKE_ARGN input) # First arg is input 41 | 42 | cmake_policy(POP) 43 | 44 | # Parse arguments 45 | set(files) 46 | set(lengths) 47 | 48 | set(output_file) 49 | set(output_length -1) 50 | 51 | foreach(arg ${CMAKE_ARGN}) 52 | if("${arg}" STREQUAL "OUTPUT") 53 | if(DEFINED output_file) 54 | list(APPEND files ${output_file}) 55 | list(APPEND lengths ${output_length}) 56 | endif() 57 | set(output_file) 58 | set(output_length -1) 59 | set(state "output") 60 | elseif("${arg}" STREQUAL "LENGTH") 61 | set(state "length") 62 | elseif("${state}" STREQUAL "output") 63 | set(output_file "${arg}") 64 | elseif("${state}" STREQUAL "length") 65 | set(output_length "${arg}") 66 | else() 67 | message(FATAL_ERROR "Invalid arguments. Check the argument list.") 68 | endif() 69 | endforeach() 70 | 71 | # add the last file 72 | if(DEFINED output_file) 73 | list(APPEND files ${output_file}) 74 | list(APPEND lengths ${output_length}) 75 | endif() 76 | 77 | # Split macros 78 | find_program(DD_EXECUTABLE NAMES dd) 79 | find_program(POWERSHELL_EXECUTABLE NAMES powershell pwsh) 80 | include("${CMAKE_CURRENT_LIST_DIR}/Hexdecode.cmake" OPTIONAL RESULT_VARIABLE HEXDECODE_INCLUDED) 81 | 82 | # Try if dd is available 83 | if(DD_EXECUTABLE) 84 | macro(do_split part length offset) 85 | if(${length} LESS 0) 86 | execute_process( 87 | COMMAND "${DD_EXECUTABLE}" if=${input} of=${part} bs=1 skip=${offset} 88 | ERROR_QUIET 89 | ) 90 | else() 91 | execute_process( 92 | COMMAND "${DD_EXECUTABLE}" if=${input} of=${part} bs=1 count=${length} skip=${offset} 93 | ERROR_QUIET 94 | ) 95 | endif() 96 | endmacro() 97 | elseif(POWERSHELL_EXECUTABLE) 98 | # Try if powershell is available 99 | macro(do_split part length offset) 100 | if(${length} LESS 0) 101 | execute_process( 102 | COMMAND "${POWERSHELL_EXECUTABLE}" -Command " 103 | & { 104 | $bytes = [System.IO.File]::ReadAllBytes('${input}'); 105 | [System.IO.File]::WriteAllBytes('${part}', $bytes[${offset}..($bytes.Length - 1)]) 106 | } 107 | " 108 | ) 109 | else() 110 | execute_process( 111 | COMMAND "${POWERSHELL_EXECUTABLE}" -Command " 112 | & { 113 | $bytes = [System.IO.File]::ReadAllBytes('${input}'); 114 | $lengthMinusOne = ${length} - 1; 115 | $lengthPlusOffset = $lengthMinusOne + ${offset}; 116 | $lengthArray = $bytes.Length - 1; 117 | if ($lengthPlusOffset -lt $lengthArray) { 118 | $newArray = $bytes[${offset}..$lengthPlusOffset]; 119 | } else { 120 | $newArray = $bytes[${offset}..$lengthArray]; 121 | } 122 | [System.IO.File]::WriteAllBytes('${part}', $newArray) 123 | } 124 | " 125 | ) 126 | endif() 127 | endmacro() 128 | elseif(HEXDECODE_INCLUDED) 129 | # Fallback to Hexdecode (SLOW!) 130 | file(READ "${input}" hexes HEX) 131 | string(LENGTH hexes hexesLength) 132 | 133 | macro(do_split part length offset) 134 | if(${length} GREATER 0) 135 | math(EXPR length2 "${length} * 2") 136 | else() 137 | set(length2 ${length}) 138 | endif() 139 | math(EXPR offset2 "${offset} * 2") 140 | 141 | if(${offset2} LESS ${hexesLength}) 142 | string(SUBSTRING "${hexes}" ${offset2} ${length2} partHex) 143 | hexdecode("${part}" ${partHex}) 144 | else() 145 | file(TOUCH "${part}") 146 | endif() 147 | endmacro() 148 | else() 149 | message(FATAL_ERROR "Failed to split file: Missing dependencies.") 150 | endif() 151 | 152 | # Splitting 153 | set(fileOffset 0) 154 | foreach(file IN ZIP_LISTS files lengths) 155 | do_split("${file_0}" ${file_1} "${fileOffset}") 156 | math(EXPR fileOffset "${fileOffset} + ${file_1}") 157 | endforeach() 158 | -------------------------------------------------------------------------------- /cmake/Modules/FindFreeImage.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Locates/Downloads/Installs the FreeImage library 4 | # 5 | # Copyright (C) 2021-2023 gba-toolchain contributors 6 | # For conditions of distribution and use, see copyright notice in LICENSE.md 7 | # 8 | #=============================================================================== 9 | 10 | include(FetchContent) 11 | 12 | find_package(FreeImage CONFIG QUIET) 13 | if(NOT FreeImage_FOUND) 14 | set(FREEIMAGE_CHECK_DIRS 15 | "${TOOLCHAIN_LIBRARY_PATH}/FreeImage" 16 | /usr 17 | /usr/local 18 | /opt 19 | /opt/local 20 | ) 21 | 22 | find_path(FREEIMAGE_INCLUDE FreeImage.h PATHS ${FREEIMAGE_CHECK_DIRS} PATH_SUFFIXES include) 23 | find_library(FREEIMAGE_LIBRARY freeimage PATHS ${FREEIMAGE_CHECK_DIRS} PATH_SUFFIXES lib) 24 | 25 | if(FREEIMAGE_INCLUDE AND FREEIMAGE_LIBRARY) 26 | add_library(freeimage::FreeImage STATIC IMPORTED) 27 | set_target_properties(freeimage::FreeImage PROPERTIES IMPORTED_LOCATION ${FREEIMAGE_LIBRARY}) 28 | target_include_directories(freeimage::FreeImage INTERFACE ${FREEIMAGE_INCLUDE}) 29 | target_compile_definitions(freeimage::FreeImage INTERFACE FREEIMAGE_LIB OPJ_STATIC DISABLE_PERF_MEASUREMENT) 30 | endif() 31 | endif() 32 | 33 | if(NOT TARGET freeimage::FreeImage) 34 | set(SOURCE_DIR "${TOOLCHAIN_LIBRARY_PATH}/FreeImage") 35 | 36 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 37 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 38 | cmake_minimum_required(VERSION 3.18) 39 | project(FreeImage C CXX) 40 | 41 | add_library(freeimage STATIC 42 | Source/FreeImage/BitmapAccess.cpp 43 | Source/FreeImage/ColorLookup.cpp 44 | Source/FreeImage/ConversionRGBA16.cpp 45 | Source/FreeImage/ConversionRGBAF.cpp 46 | Source/FreeImage/FreeImage.cpp 47 | Source/FreeImage/FreeImageC.c 48 | Source/FreeImage/FreeImageIO.cpp 49 | Source/FreeImage/GetType.cpp 50 | Source/FreeImage/LFPQuantizer.cpp 51 | Source/FreeImage/MemoryIO.cpp 52 | Source/FreeImage/PixelAccess.cpp 53 | Source/FreeImage/J2KHelper.cpp 54 | Source/FreeImage/MNGHelper.cpp 55 | Source/FreeImage/Plugin.cpp 56 | Source/FreeImage/PluginBMP.cpp 57 | Source/FreeImage/PluginCUT.cpp 58 | Source/FreeImage/PluginDDS.cpp 59 | Source/FreeImage/PluginEXR.cpp 60 | Source/FreeImage/PluginG3.cpp 61 | Source/FreeImage/PluginGIF.cpp 62 | Source/FreeImage/PluginHDR.cpp 63 | Source/FreeImage/PluginICO.cpp 64 | Source/FreeImage/PluginIFF.cpp 65 | Source/FreeImage/PluginJ2K.cpp 66 | Source/FreeImage/PluginJNG.cpp 67 | Source/FreeImage/PluginJP2.cpp 68 | Source/FreeImage/PluginJPEG.cpp 69 | Source/FreeImage/PluginJXR.cpp 70 | Source/FreeImage/PluginKOALA.cpp 71 | Source/FreeImage/PluginMNG.cpp 72 | Source/FreeImage/PluginPCD.cpp 73 | Source/FreeImage/PluginPCX.cpp 74 | Source/FreeImage/PluginPFM.cpp 75 | Source/FreeImage/PluginPICT.cpp 76 | Source/FreeImage/PluginPNG.cpp 77 | Source/FreeImage/PluginPNM.cpp 78 | Source/FreeImage/PluginPSD.cpp 79 | Source/FreeImage/PluginRAS.cpp 80 | Source/FreeImage/PluginRAW.cpp 81 | Source/FreeImage/PluginSGI.cpp 82 | Source/FreeImage/PluginTARGA.cpp 83 | Source/FreeImage/PluginTIFF.cpp 84 | Source/FreeImage/PluginWBMP.cpp 85 | Source/FreeImage/PluginWebP.cpp 86 | Source/FreeImage/PluginXBM.cpp 87 | Source/FreeImage/PluginXPM.cpp 88 | Source/FreeImage/PSDParser.cpp 89 | Source/FreeImage/TIFFLogLuv.cpp 90 | Source/FreeImage/Conversion.cpp 91 | Source/FreeImage/Conversion16_555.cpp 92 | Source/FreeImage/Conversion16_565.cpp 93 | Source/FreeImage/Conversion24.cpp 94 | Source/FreeImage/Conversion32.cpp 95 | Source/FreeImage/Conversion4.cpp 96 | Source/FreeImage/Conversion8.cpp 97 | Source/FreeImage/ConversionFloat.cpp 98 | Source/FreeImage/ConversionRGB16.cpp 99 | Source/FreeImage/ConversionRGBF.cpp 100 | Source/FreeImage/ConversionType.cpp 101 | Source/FreeImage/ConversionUINT16.cpp 102 | Source/FreeImage/Halftoning.cpp 103 | Source/FreeImage/tmoColorConvert.cpp 104 | Source/FreeImage/tmoDrago03.cpp 105 | Source/FreeImage/tmoFattal02.cpp 106 | Source/FreeImage/tmoReinhard05.cpp 107 | Source/FreeImage/ToneMapping.cpp 108 | Source/FreeImage/NNQuantizer.cpp 109 | Source/FreeImage/WuQuantizer.cpp 110 | Source/FreeImage/CacheFile.cpp 111 | Source/FreeImage/MultiPage.cpp 112 | Source/FreeImage/ZLibInterface.cpp 113 | Source/Metadata/Exif.cpp 114 | Source/Metadata/FIRational.cpp 115 | Source/Metadata/FreeImageTag.cpp 116 | Source/Metadata/IPTC.cpp 117 | Source/Metadata/TagConversion.cpp 118 | Source/Metadata/TagLib.cpp 119 | Source/Metadata/XTIFF.cpp 120 | Source/FreeImageToolkit/Background.cpp 121 | Source/FreeImageToolkit/BSplineRotate.cpp 122 | Source/FreeImageToolkit/Channels.cpp 123 | Source/FreeImageToolkit/ClassicRotate.cpp 124 | Source/FreeImageToolkit/Colors.cpp 125 | Source/FreeImageToolkit/CopyPaste.cpp 126 | Source/FreeImageToolkit/Display.cpp 127 | Source/FreeImageToolkit/Flip.cpp 128 | Source/FreeImageToolkit/JPEGTransform.cpp 129 | Source/FreeImageToolkit/MultigridPoissonSolver.cpp 130 | Source/FreeImageToolkit/Rescale.cpp 131 | Source/FreeImageToolkit/Resize.cpp 132 | Source/LibJPEG/jaricom.c 133 | Source/LibJPEG/jcapimin.c 134 | Source/LibJPEG/jcapistd.c 135 | Source/LibJPEG/jcarith.c 136 | Source/LibJPEG/jccoefct.c 137 | Source/LibJPEG/jccolor.c 138 | Source/LibJPEG/jcdctmgr.c 139 | Source/LibJPEG/jchuff.c 140 | Source/LibJPEG/jcinit.c 141 | Source/LibJPEG/jcmainct.c 142 | Source/LibJPEG/jcmarker.c 143 | Source/LibJPEG/jcmaster.c 144 | Source/LibJPEG/jcomapi.c 145 | Source/LibJPEG/jcparam.c 146 | Source/LibJPEG/jcprepct.c 147 | Source/LibJPEG/jcsample.c 148 | Source/LibJPEG/jctrans.c 149 | Source/LibJPEG/jdapimin.c 150 | Source/LibJPEG/jdapistd.c 151 | Source/LibJPEG/jdarith.c 152 | Source/LibJPEG/jdatadst.c 153 | Source/LibJPEG/jdatasrc.c 154 | Source/LibJPEG/jdcoefct.c 155 | Source/LibJPEG/jdcolor.c 156 | Source/LibJPEG/jddctmgr.c 157 | Source/LibJPEG/jdhuff.c 158 | Source/LibJPEG/jdinput.c 159 | Source/LibJPEG/jdmainct.c 160 | Source/LibJPEG/jdmarker.c 161 | Source/LibJPEG/jdmaster.c 162 | Source/LibJPEG/jdmerge.c 163 | Source/LibJPEG/jdpostct.c 164 | Source/LibJPEG/jdsample.c 165 | Source/LibJPEG/jdtrans.c 166 | Source/LibJPEG/jerror.c 167 | Source/LibJPEG/jfdctflt.c 168 | Source/LibJPEG/jfdctfst.c 169 | Source/LibJPEG/jfdctint.c 170 | Source/LibJPEG/jidctflt.c 171 | Source/LibJPEG/jidctfst.c 172 | Source/LibJPEG/jidctint.c 173 | Source/LibJPEG/jmemmgr.c 174 | Source/LibJPEG/jmemnobs.c 175 | Source/LibJPEG/jquant1.c 176 | Source/LibJPEG/jquant2.c 177 | Source/LibJPEG/jutils.c 178 | Source/LibJPEG/transupp.c 179 | Source/LibPNG/png.c 180 | Source/LibPNG/pngerror.c 181 | Source/LibPNG/pngget.c 182 | Source/LibPNG/pngmem.c 183 | Source/LibPNG/pngpread.c 184 | Source/LibPNG/pngread.c 185 | Source/LibPNG/pngrio.c 186 | Source/LibPNG/pngrtran.c 187 | Source/LibPNG/pngrutil.c 188 | Source/LibPNG/pngset.c 189 | Source/LibPNG/pngtrans.c 190 | Source/LibPNG/pngwio.c 191 | Source/LibPNG/pngwrite.c 192 | Source/LibPNG/pngwtran.c 193 | Source/LibPNG/pngwutil.c 194 | Source/LibTIFF4/tif_aux.c 195 | Source/LibTIFF4/tif_close.c 196 | Source/LibTIFF4/tif_codec.c 197 | Source/LibTIFF4/tif_color.c 198 | Source/LibTIFF4/tif_compress.c 199 | Source/LibTIFF4/tif_dir.c 200 | Source/LibTIFF4/tif_dirinfo.c 201 | Source/LibTIFF4/tif_dirread.c 202 | Source/LibTIFF4/tif_dirwrite.c 203 | Source/LibTIFF4/tif_dumpmode.c 204 | Source/LibTIFF4/tif_error.c 205 | Source/LibTIFF4/tif_extension.c 206 | Source/LibTIFF4/tif_fax3.c 207 | Source/LibTIFF4/tif_fax3sm.c 208 | Source/LibTIFF4/tif_flush.c 209 | Source/LibTIFF4/tif_getimage.c 210 | Source/LibTIFF4/tif_jpeg.c 211 | Source/LibTIFF4/tif_luv.c 212 | Source/LibTIFF4/tif_lzma.c 213 | Source/LibTIFF4/tif_lzw.c 214 | Source/LibTIFF4/tif_next.c 215 | Source/LibTIFF4/tif_ojpeg.c 216 | Source/LibTIFF4/tif_open.c 217 | Source/LibTIFF4/tif_packbits.c 218 | Source/LibTIFF4/tif_pixarlog.c 219 | Source/LibTIFF4/tif_predict.c 220 | Source/LibTIFF4/tif_print.c 221 | Source/LibTIFF4/tif_read.c 222 | Source/LibTIFF4/tif_strip.c 223 | Source/LibTIFF4/tif_swab.c 224 | Source/LibTIFF4/tif_thunder.c 225 | Source/LibTIFF4/tif_tile.c 226 | Source/LibTIFF4/tif_version.c 227 | Source/LibTIFF4/tif_warning.c 228 | Source/LibTIFF4/tif_write.c 229 | Source/LibTIFF4/tif_zip.c 230 | Source/ZLib/adler32.c 231 | Source/ZLib/compress.c 232 | Source/ZLib/crc32.c 233 | Source/ZLib/deflate.c 234 | Source/ZLib/gzclose.c 235 | Source/ZLib/gzlib.c 236 | Source/ZLib/gzread.c 237 | Source/ZLib/gzwrite.c 238 | Source/ZLib/infback.c 239 | Source/ZLib/inffast.c 240 | Source/ZLib/inflate.c 241 | Source/ZLib/inftrees.c 242 | Source/ZLib/trees.c 243 | Source/ZLib/uncompr.c 244 | Source/ZLib/zutil.c 245 | Source/LibOpenJPEG/bio.c 246 | Source/LibOpenJPEG/cio.c 247 | Source/LibOpenJPEG/dwt.c 248 | Source/LibOpenJPEG/event.c 249 | Source/LibOpenJPEG/function_list.c 250 | Source/LibOpenJPEG/image.c 251 | Source/LibOpenJPEG/invert.c 252 | Source/LibOpenJPEG/j2k.c 253 | Source/LibOpenJPEG/jp2.c 254 | Source/LibOpenJPEG/mct.c 255 | Source/LibOpenJPEG/mqc.c 256 | Source/LibOpenJPEG/openjpeg.c 257 | Source/LibOpenJPEG/opj_clock.c 258 | Source/LibOpenJPEG/pi.c 259 | Source/LibOpenJPEG/raw.c 260 | Source/LibOpenJPEG/t1.c 261 | Source/LibOpenJPEG/t2.c 262 | Source/LibOpenJPEG/tcd.c 263 | Source/LibOpenJPEG/tgt.c 264 | Source/OpenEXR/IexMath/IexMathFpu.cpp 265 | Source/OpenEXR/IlmImf/b44ExpLogTable.cpp 266 | Source/OpenEXR/IlmImf/ImfAcesFile.cpp 267 | Source/OpenEXR/IlmImf/ImfAttribute.cpp 268 | Source/OpenEXR/IlmImf/ImfB44Compressor.cpp 269 | Source/OpenEXR/IlmImf/ImfBoxAttribute.cpp 270 | Source/OpenEXR/IlmImf/ImfChannelList.cpp 271 | Source/OpenEXR/IlmImf/ImfChannelListAttribute.cpp 272 | Source/OpenEXR/IlmImf/ImfChromaticities.cpp 273 | Source/OpenEXR/IlmImf/ImfChromaticitiesAttribute.cpp 274 | Source/OpenEXR/IlmImf/ImfCompositeDeepScanLine.cpp 275 | Source/OpenEXR/IlmImf/ImfCompressionAttribute.cpp 276 | Source/OpenEXR/IlmImf/ImfCompressor.cpp 277 | Source/OpenEXR/IlmImf/ImfConvert.cpp 278 | Source/OpenEXR/IlmImf/ImfCRgbaFile.cpp 279 | Source/OpenEXR/IlmImf/ImfDeepCompositing.cpp 280 | Source/OpenEXR/IlmImf/ImfDeepFrameBuffer.cpp 281 | Source/OpenEXR/IlmImf/ImfDeepImageStateAttribute.cpp 282 | Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp 283 | Source/OpenEXR/IlmImf/ImfDeepScanLineInputPart.cpp 284 | Source/OpenEXR/IlmImf/ImfDeepScanLineOutputFile.cpp 285 | Source/OpenEXR/IlmImf/ImfDeepScanLineOutputPart.cpp 286 | Source/OpenEXR/IlmImf/ImfDeepTiledInputFile.cpp 287 | Source/OpenEXR/IlmImf/ImfDeepTiledInputPart.cpp 288 | Source/OpenEXR/IlmImf/ImfDeepTiledOutputFile.cpp 289 | Source/OpenEXR/IlmImf/ImfDeepTiledOutputPart.cpp 290 | Source/OpenEXR/IlmImf/ImfDoubleAttribute.cpp 291 | Source/OpenEXR/IlmImf/ImfDwaCompressor.cpp 292 | Source/OpenEXR/IlmImf/ImfEnvmap.cpp 293 | Source/OpenEXR/IlmImf/ImfEnvmapAttribute.cpp 294 | Source/OpenEXR/IlmImf/ImfFastHuf.cpp 295 | Source/OpenEXR/IlmImf/ImfFloatAttribute.cpp 296 | Source/OpenEXR/IlmImf/ImfFloatVectorAttribute.cpp 297 | Source/OpenEXR/IlmImf/ImfFrameBuffer.cpp 298 | Source/OpenEXR/IlmImf/ImfFramesPerSecond.cpp 299 | Source/OpenEXR/IlmImf/ImfGenericInputFile.cpp 300 | Source/OpenEXR/IlmImf/ImfGenericOutputFile.cpp 301 | Source/OpenEXR/IlmImf/ImfHeader.cpp 302 | Source/OpenEXR/IlmImf/ImfHuf.cpp 303 | Source/OpenEXR/IlmImf/ImfInputFile.cpp 304 | Source/OpenEXR/IlmImf/ImfInputPart.cpp 305 | Source/OpenEXR/IlmImf/ImfInputPartData.cpp 306 | Source/OpenEXR/IlmImf/ImfIntAttribute.cpp 307 | Source/OpenEXR/IlmImf/ImfIO.cpp 308 | Source/OpenEXR/IlmImf/ImfKeyCode.cpp 309 | Source/OpenEXR/IlmImf/ImfKeyCodeAttribute.cpp 310 | Source/OpenEXR/IlmImf/ImfLineOrderAttribute.cpp 311 | Source/OpenEXR/IlmImf/ImfLut.cpp 312 | Source/OpenEXR/IlmImf/ImfMatrixAttribute.cpp 313 | Source/OpenEXR/IlmImf/ImfMisc.cpp 314 | Source/OpenEXR/IlmImf/ImfMultiPartInputFile.cpp 315 | Source/OpenEXR/IlmImf/ImfMultiPartOutputFile.cpp 316 | Source/OpenEXR/IlmImf/ImfMultiView.cpp 317 | Source/OpenEXR/IlmImf/ImfOpaqueAttribute.cpp 318 | Source/OpenEXR/IlmImf/ImfOutputFile.cpp 319 | Source/OpenEXR/IlmImf/ImfOutputPart.cpp 320 | Source/OpenEXR/IlmImf/ImfOutputPartData.cpp 321 | Source/OpenEXR/IlmImf/ImfPartType.cpp 322 | Source/OpenEXR/IlmImf/ImfPizCompressor.cpp 323 | Source/OpenEXR/IlmImf/ImfPreviewImage.cpp 324 | Source/OpenEXR/IlmImf/ImfPreviewImageAttribute.cpp 325 | Source/OpenEXR/IlmImf/ImfPxr24Compressor.cpp 326 | Source/OpenEXR/IlmImf/ImfRational.cpp 327 | Source/OpenEXR/IlmImf/ImfRationalAttribute.cpp 328 | Source/OpenEXR/IlmImf/ImfRgbaFile.cpp 329 | Source/OpenEXR/IlmImf/ImfRgbaYca.cpp 330 | Source/OpenEXR/IlmImf/ImfRle.cpp 331 | Source/OpenEXR/IlmImf/ImfRleCompressor.cpp 332 | Source/OpenEXR/IlmImf/ImfScanLineInputFile.cpp 333 | Source/OpenEXR/IlmImf/ImfStandardAttributes.cpp 334 | Source/OpenEXR/IlmImf/ImfStdIO.cpp 335 | Source/OpenEXR/IlmImf/ImfStringAttribute.cpp 336 | Source/OpenEXR/IlmImf/ImfStringVectorAttribute.cpp 337 | Source/OpenEXR/IlmImf/ImfSystemSpecific.cpp 338 | Source/OpenEXR/IlmImf/ImfTestFile.cpp 339 | Source/OpenEXR/IlmImf/ImfThreading.cpp 340 | Source/OpenEXR/IlmImf/ImfTileDescriptionAttribute.cpp 341 | Source/OpenEXR/IlmImf/ImfTiledInputFile.cpp 342 | Source/OpenEXR/IlmImf/ImfTiledInputPart.cpp 343 | Source/OpenEXR/IlmImf/ImfTiledMisc.cpp 344 | Source/OpenEXR/IlmImf/ImfTiledOutputFile.cpp 345 | Source/OpenEXR/IlmImf/ImfTiledOutputPart.cpp 346 | Source/OpenEXR/IlmImf/ImfTiledRgbaFile.cpp 347 | Source/OpenEXR/IlmImf/ImfTileOffsets.cpp 348 | Source/OpenEXR/IlmImf/ImfTimeCode.cpp 349 | Source/OpenEXR/IlmImf/ImfTimeCodeAttribute.cpp 350 | Source/OpenEXR/IlmImf/ImfVecAttribute.cpp 351 | Source/OpenEXR/IlmImf/ImfVersion.cpp 352 | Source/OpenEXR/IlmImf/ImfWav.cpp 353 | Source/OpenEXR/IlmImf/ImfZip.cpp 354 | Source/OpenEXR/IlmImf/ImfZipCompressor.cpp 355 | Source/OpenEXR/Imath/ImathBox.cpp 356 | Source/OpenEXR/Imath/ImathColorAlgo.cpp 357 | Source/OpenEXR/Imath/ImathFun.cpp 358 | Source/OpenEXR/Imath/ImathMatrixAlgo.cpp 359 | Source/OpenEXR/Imath/ImathRandom.cpp 360 | Source/OpenEXR/Imath/ImathShear.cpp 361 | Source/OpenEXR/Imath/ImathVec.cpp 362 | Source/OpenEXR/Iex/IexBaseExc.cpp 363 | Source/OpenEXR/Iex/IexThrowErrnoExc.cpp 364 | Source/OpenEXR/Half/half.cpp 365 | Source/OpenEXR/IlmThread/IlmThread.cpp 366 | Source/OpenEXR/IlmThread/IlmThreadMutex.cpp 367 | Source/OpenEXR/IlmThread/IlmThreadPool.cpp 368 | Source/OpenEXR/IlmThread/IlmThreadSemaphore.cpp 369 | Source/OpenEXR/IexMath/IexMathFloatExc.cpp 370 | Source/LibRawLite/internal/dcraw_common.cpp 371 | Source/LibRawLite/internal/dcraw_fileio.cpp 372 | Source/LibRawLite/internal/demosaic_packs.cpp 373 | Source/LibRawLite/src/libraw_c_api.cpp 374 | Source/LibRawLite/src/libraw_cxx.cpp 375 | Source/LibRawLite/src/libraw_datastream.cpp 376 | Source/LibWebP/src/dec/alpha_dec.c 377 | Source/LibWebP/src/dec/buffer_dec.c 378 | Source/LibWebP/src/dec/frame_dec.c 379 | Source/LibWebP/src/dec/idec_dec.c 380 | Source/LibWebP/src/dec/io_dec.c 381 | Source/LibWebP/src/dec/quant_dec.c 382 | Source/LibWebP/src/dec/tree_dec.c 383 | Source/LibWebP/src/dec/vp8l_dec.c 384 | Source/LibWebP/src/dec/vp8_dec.c 385 | Source/LibWebP/src/dec/webp_dec.c 386 | Source/LibWebP/src/demux/anim_decode.c 387 | Source/LibWebP/src/demux/demux.c 388 | Source/LibWebP/src/dsp/alpha_processing.c 389 | Source/LibWebP/src/dsp/alpha_processing_mips_dsp_r2.c 390 | Source/LibWebP/src/dsp/alpha_processing_neon.c 391 | Source/LibWebP/src/dsp/alpha_processing_sse2.c 392 | Source/LibWebP/src/dsp/alpha_processing_sse41.c 393 | Source/LibWebP/src/dsp/cost.c 394 | Source/LibWebP/src/dsp/cost_mips32.c 395 | Source/LibWebP/src/dsp/cost_mips_dsp_r2.c 396 | Source/LibWebP/src/dsp/cost_sse2.c 397 | Source/LibWebP/src/dsp/cpu.c 398 | Source/LibWebP/src/dsp/dec.c 399 | Source/LibWebP/src/dsp/dec_clip_tables.c 400 | Source/LibWebP/src/dsp/dec_mips32.c 401 | Source/LibWebP/src/dsp/dec_mips_dsp_r2.c 402 | Source/LibWebP/src/dsp/dec_msa.c 403 | Source/LibWebP/src/dsp/dec_neon.c 404 | Source/LibWebP/src/dsp/dec_sse2.c 405 | Source/LibWebP/src/dsp/dec_sse41.c 406 | Source/LibWebP/src/dsp/enc.c 407 | Source/LibWebP/src/dsp/enc_avx2.c 408 | Source/LibWebP/src/dsp/enc_mips32.c 409 | Source/LibWebP/src/dsp/enc_mips_dsp_r2.c 410 | Source/LibWebP/src/dsp/enc_msa.c 411 | Source/LibWebP/src/dsp/enc_neon.c 412 | Source/LibWebP/src/dsp/enc_sse2.c 413 | Source/LibWebP/src/dsp/enc_sse41.c 414 | Source/LibWebP/src/dsp/filters.c 415 | Source/LibWebP/src/dsp/filters_mips_dsp_r2.c 416 | Source/LibWebP/src/dsp/filters_msa.c 417 | Source/LibWebP/src/dsp/filters_neon.c 418 | Source/LibWebP/src/dsp/filters_sse2.c 419 | Source/LibWebP/src/dsp/lossless.c 420 | Source/LibWebP/src/dsp/lossless_enc.c 421 | Source/LibWebP/src/dsp/lossless_enc_mips32.c 422 | Source/LibWebP/src/dsp/lossless_enc_mips_dsp_r2.c 423 | Source/LibWebP/src/dsp/lossless_enc_msa.c 424 | Source/LibWebP/src/dsp/lossless_enc_neon.c 425 | Source/LibWebP/src/dsp/lossless_enc_sse2.c 426 | Source/LibWebP/src/dsp/lossless_enc_sse41.c 427 | Source/LibWebP/src/dsp/lossless_mips_dsp_r2.c 428 | Source/LibWebP/src/dsp/lossless_msa.c 429 | Source/LibWebP/src/dsp/lossless_neon.c 430 | Source/LibWebP/src/dsp/lossless_sse2.c 431 | Source/LibWebP/src/dsp/rescaler.c 432 | Source/LibWebP/src/dsp/rescaler_mips32.c 433 | Source/LibWebP/src/dsp/rescaler_mips_dsp_r2.c 434 | Source/LibWebP/src/dsp/rescaler_msa.c 435 | Source/LibWebP/src/dsp/rescaler_neon.c 436 | Source/LibWebP/src/dsp/rescaler_sse2.c 437 | Source/LibWebP/src/dsp/ssim.c 438 | Source/LibWebP/src/dsp/ssim_sse2.c 439 | Source/LibWebP/src/dsp/upsampling.c 440 | Source/LibWebP/src/dsp/upsampling_mips_dsp_r2.c 441 | Source/LibWebP/src/dsp/upsampling_msa.c 442 | Source/LibWebP/src/dsp/upsampling_neon.c 443 | Source/LibWebP/src/dsp/upsampling_sse2.c 444 | Source/LibWebP/src/dsp/upsampling_sse41.c 445 | Source/LibWebP/src/dsp/yuv.c 446 | Source/LibWebP/src/dsp/yuv_mips32.c 447 | Source/LibWebP/src/dsp/yuv_mips_dsp_r2.c 448 | Source/LibWebP/src/dsp/yuv_neon.c 449 | Source/LibWebP/src/dsp/yuv_sse2.c 450 | Source/LibWebP/src/dsp/yuv_sse41.c 451 | Source/LibWebP/src/enc/alpha_enc.c 452 | Source/LibWebP/src/enc/analysis_enc.c 453 | Source/LibWebP/src/enc/backward_references_cost_enc.c 454 | Source/LibWebP/src/enc/backward_references_enc.c 455 | Source/LibWebP/src/enc/config_enc.c 456 | Source/LibWebP/src/enc/cost_enc.c 457 | Source/LibWebP/src/enc/filter_enc.c 458 | Source/LibWebP/src/enc/frame_enc.c 459 | Source/LibWebP/src/enc/histogram_enc.c 460 | Source/LibWebP/src/enc/iterator_enc.c 461 | Source/LibWebP/src/enc/near_lossless_enc.c 462 | Source/LibWebP/src/enc/picture_csp_enc.c 463 | Source/LibWebP/src/enc/picture_enc.c 464 | Source/LibWebP/src/enc/picture_psnr_enc.c 465 | Source/LibWebP/src/enc/picture_rescale_enc.c 466 | Source/LibWebP/src/enc/picture_tools_enc.c 467 | Source/LibWebP/src/enc/predictor_enc.c 468 | Source/LibWebP/src/enc/quant_enc.c 469 | Source/LibWebP/src/enc/syntax_enc.c 470 | Source/LibWebP/src/enc/token_enc.c 471 | Source/LibWebP/src/enc/tree_enc.c 472 | Source/LibWebP/src/enc/vp8l_enc.c 473 | Source/LibWebP/src/enc/webp_enc.c 474 | Source/LibWebP/src/mux/anim_encode.c 475 | Source/LibWebP/src/mux/muxedit.c 476 | Source/LibWebP/src/mux/muxinternal.c 477 | Source/LibWebP/src/mux/muxread.c 478 | Source/LibWebP/src/utils/bit_reader_utils.c 479 | Source/LibWebP/src/utils/bit_writer_utils.c 480 | Source/LibWebP/src/utils/color_cache_utils.c 481 | Source/LibWebP/src/utils/filters_utils.c 482 | Source/LibWebP/src/utils/huffman_encode_utils.c 483 | Source/LibWebP/src/utils/huffman_utils.c 484 | Source/LibWebP/src/utils/quant_levels_dec_utils.c 485 | Source/LibWebP/src/utils/quant_levels_utils.c 486 | Source/LibWebP/src/utils/random_utils.c 487 | Source/LibWebP/src/utils/rescaler_utils.c 488 | Source/LibWebP/src/utils/thread_utils.c 489 | Source/LibWebP/src/utils/utils.c 490 | Source/LibJXR/image/decode/decode.c 491 | Source/LibJXR/image/decode/JXRTranscode.c 492 | Source/LibJXR/image/decode/postprocess.c 493 | Source/LibJXR/image/decode/segdec.c 494 | Source/LibJXR/image/decode/strdec.c 495 | Source/LibJXR/image/decode/strdec_x86.c 496 | Source/LibJXR/image/decode/strInvTransform.c 497 | Source/LibJXR/image/decode/strPredQuantDec.c 498 | Source/LibJXR/image/encode/encode.c 499 | Source/LibJXR/image/encode/segenc.c 500 | Source/LibJXR/image/encode/strenc.c 501 | Source/LibJXR/image/encode/strenc_x86.c 502 | Source/LibJXR/image/encode/strFwdTransform.c 503 | Source/LibJXR/image/encode/strPredQuantEnc.c 504 | Source/LibJXR/image/sys/adapthuff.c 505 | Source/LibJXR/image/sys/image.c 506 | Source/LibJXR/image/sys/strcodec.c 507 | Source/LibJXR/image/sys/strPredQuant.c 508 | Source/LibJXR/image/sys/strTransform.c 509 | Source/LibJXR/jxrgluelib/JXRGlue.c 510 | Source/LibJXR/jxrgluelib/JXRGlueJxr.c 511 | Source/LibJXR/jxrgluelib/JXRGluePFC.c 512 | Source/LibJXR/jxrgluelib/JXRMeta.c 513 | ) 514 | target_include_directories(freeimage PRIVATE 515 | Source 516 | Source/Metadata 517 | Source/FreeImageToolkit 518 | Source/LibJPEG 519 | Source/LibPNG 520 | Source/LibTIFF4 521 | Source/ZLib 522 | Source/LibOpenJPEG 523 | Source/OpenEXR 524 | Source/OpenEXR/Half 525 | Source/OpenEXR/Iex 526 | Source/OpenEXR/IlmImf 527 | Source/OpenEXR/IlmThread 528 | Source/OpenEXR/Imath 529 | Source/OpenEXR/IexMath 530 | Source/LibRawLite 531 | Source/LibRawLite/dcraw 532 | Source/LibRawLite/internal 533 | Source/LibRawLite/libraw 534 | Source/LibRawLite/src 535 | Source/LibWebP 536 | Source/LibJXR 537 | Source/LibJXR/common/include 538 | Source/LibJXR/image/sys 539 | Source/LibJXR/jxrgluelib 540 | ) 541 | target_compile_definitions(freeimage PRIVATE FREEIMAGE_LIB LIBRAW_NODLL OPJ_STATIC DISABLE_PERF_MEASUREMENT) 542 | 543 | if(MSVC) 544 | target_compile_options(freeimage PRIVATE 545 | "/wd4789;" # disable "buffer 'identifier' of size N bytes will be overrun; M bytes will be written starting at offset L" warnings 546 | "/wd4311;" # disable "'variable' : pointer truncation from 'type' to 'type'" warnings 547 | "/wd4804;" # disable "'operation' : unsafe use of type 'bool' in operation" warnings 548 | "/wd4806;" # disable "'operation' : unsafe operation: no value of type 'type' promoted to type 'type' can equal the given constant" warnings 549 | "/wd4722;" # disable "'function' : destructor never returns, potential memory leak" warnings 550 | ) 551 | endif() 552 | 553 | install(TARGETS freeimage 554 | LIBRARY DESTINATION lib 555 | ) 556 | install(FILES Source/FreeImage.h 557 | DESTINATION include 558 | ) 559 | ]=]) 560 | 561 | FetchContent_Declare(freeimage_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 562 | PREFIX "${SOURCE_DIR}" 563 | TMP_DIR "${SOURCE_DIR}/temp" 564 | STAMP_DIR "${SOURCE_DIR}/stamp" 565 | SOURCE_DIR "${SOURCE_DIR}/source" 566 | # Download 567 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 568 | GIT_REPOSITORY "https://github.com/WinMerge/freeimage.git" 569 | GIT_TAG "master" 570 | # Update 571 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy_if_different 572 | "${SOURCE_DIR}/temp/CMakeLists.txt" 573 | "${SOURCE_DIR}/source/CMakeLists.txt" 574 | ) 575 | 576 | FetchContent_MakeAvailable(freeimage_proj) 577 | 578 | # Configure 579 | execute_process( 580 | COMMAND "${CMAKE_COMMAND}" -S . -B "${SOURCE_DIR}/build" 581 | WORKING_DIRECTORY "${SOURCE_DIR}/source" 582 | RESULT_VARIABLE cmakeResult 583 | ) 584 | 585 | if(cmakeResult EQUAL "1") 586 | message(WARNING "Failed to configure FreeImage") 587 | else() 588 | # Build 589 | execute_process( 590 | COMMAND "${CMAKE_COMMAND}" --build . --config Release 591 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 592 | RESULT_VARIABLE cmakeResult 593 | ) 594 | 595 | if(cmakeResult EQUAL "1") 596 | message(WARNING "Failed to build FreeImage") 597 | else() 598 | # Install 599 | execute_process( 600 | COMMAND ${CMAKE_COMMAND} --install . --prefix "${SOURCE_DIR}" --config Release 601 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 602 | RESULT_VARIABLE cmakeResult 603 | ) 604 | 605 | if(cmakeResult EQUAL "1") 606 | message(WARNING "Failed to install FreeImage") 607 | else() 608 | find_path(FREEIMAGE_INCLUDE FreeImage.h PATHS "${TOOLCHAIN_LIBRARY_PATH}/FreeImage" PATH_SUFFIXES include) 609 | find_library(FREEIMAGE_LIBRARY freeimage PATHS "${TOOLCHAIN_LIBRARY_PATH}/FreeImage" PATH_SUFFIXES lib) 610 | 611 | add_library(freeimage::FreeImage STATIC IMPORTED) 612 | set_target_properties(freeimage::FreeImage PROPERTIES IMPORTED_LOCATION ${FREEIMAGE_LIBRARY}) 613 | target_include_directories(freeimage::FreeImage INTERFACE ${FREEIMAGE_INCLUDE}) 614 | target_compile_definitions(freeimage::FreeImage INTERFACE FREEIMAGE_LIB OPJ_STATIC DISABLE_PERF_MEASUREMENT) 615 | endif() 616 | endif() 617 | endif() 618 | endif() 619 | -------------------------------------------------------------------------------- /cmake/Modules/Findagbabi.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(FetchContent) 9 | 10 | if(EXISTS "${CMAKE_SYSTEM_LIBRARY_PATH}/agbabi/CMakeLists.txt" OR EXISTS "${CMAKE_BINARY_DIR}/lib/agbabi/CMakeLists.txt") 11 | add_subdirectory("${CMAKE_SYSTEM_LIBRARY_PATH}/agbabi" "${CMAKE_BINARY_DIR}/lib/agbabi" EXCLUDE_FROM_ALL) 12 | else() 13 | find_library(libagbabi agbabi PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/agbabi" "${AGBABI_DIR}" PATH_SUFFIXES lib) 14 | 15 | if(NOT libagbabi) 16 | FetchContent_Declare(agbabi DOWNLOAD_EXTRACT_TIMESTAMP ON 17 | SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/agbabi" 18 | GIT_REPOSITORY "https://github.com/felixjones/agbabi.git" 19 | GIT_TAG "main" 20 | ) 21 | 22 | FetchContent_MakeAvailable(agbabi) 23 | else() 24 | add_library(agbabi STATIC IMPORTED) 25 | set_property(TARGET agbabi PROPERTY IMPORTED_LOCATION "${libagbabi}") 26 | 27 | get_filename_component(INCLUDE_PATH "${libagbabi}" DIRECTORY) 28 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 29 | target_include_directories(agbabi INTERFACE "${INCLUDE_PATH}/include") 30 | 31 | unset(libagbabi CACHE) 32 | endif() 33 | endif() 34 | -------------------------------------------------------------------------------- /cmake/Modules/Findbutano.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | enable_language(ASM C CXX) 9 | 10 | include(FetchContent) 11 | 12 | # Butano dependencies 13 | if(NOT Python_EXECUTABLE) 14 | find_package(Python COMPONENTS Interpreter REQUIRED) 15 | endif() 16 | 17 | if(NOT CMAKE_GRIT_PROGRAM) 18 | find_package(grit REQUIRED) 19 | endif() 20 | 21 | if(NOT CMAKE_MMUTIL_PROGRAM) 22 | find_package(maxmod REQUIRED) 23 | endif() 24 | 25 | include(Bin2s) 26 | 27 | # Find butano 28 | find_path(BUTANO_DIR NAMES butano/butano.mak PATHS "$ENV{DEVKITPRO}/butano" "${CMAKE_SYSTEM_LIBRARY_PATH}/butano" "${BUTANO_DIR}" PATH_SUFFIXES source NO_CACHE) 29 | 30 | if(NOT BUTANO_DIR) 31 | unset(BUTANO_DIR CACHE) 32 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/butano") 33 | 34 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 35 | FetchContent_Declare(butano DOWNLOAD_EXTRACT_TIMESTAMP ON 36 | PREFIX "${SOURCE_DIR}" 37 | TMP_DIR "${SOURCE_DIR}/temp" 38 | STAMP_DIR "${SOURCE_DIR}/stamp" 39 | SOURCE_DIR "${SOURCE_DIR}/source" 40 | # Download 41 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 42 | GIT_REPOSITORY "https://github.com/GValiente/butano.git" 43 | GIT_TAG "master" 44 | ) 45 | 46 | FetchContent_Populate(butano) 47 | if(NOT butano_SOURCE_DIR) 48 | message(FATAL_ERROR "Failed to fetch butano") 49 | endif() 50 | set(BUTANO_DIR "${butano_SOURCE_DIR}" CACHE PATH "Path to Butano directory" FORCE) 51 | endif() 52 | 53 | if(NOT EXISTS "${BUTANO_DIR}/CMakeLists.txt") 54 | file(WRITE "${BUTANO_DIR}/CMakeLists.txt" [=[ 55 | cmake_minimum_required(VERSION 3.18) 56 | project(butano ASM C CXX) 57 | 58 | if(NOT CMAKE_SYSTEM_NAME STREQUAL AdvancedGameBoy) 59 | message(FATAL_ERROR "Butano is a library for AdvancedGameBoy") 60 | endif() 61 | 62 | # Butano is as an OBJECT library 63 | file(GLOB src "butano/src/*.cpp") 64 | file(GLOB hw_src "butano/hw/src/*.cpp") 65 | file(GLOB hw_asm "butano/hw/src/*.s") 66 | 67 | # 3rd party code 68 | file(GLOB_RECURSE cpp_3rd_party "butano/hw/3rd_party/*.cpp") 69 | file(GLOB_RECURSE c_3rd_party "butano/hw/3rd_party/*.c") 70 | file(GLOB_RECURSE asm_3rd_party "butano/hw/3rd_party/*.s") 71 | 72 | add_library(butano OBJECT ${src} ${hw_src} ${hw_asm} 73 | ${cpp_3rd_party} 74 | ${c_3rd_party} 75 | ${asm_3rd_party} 76 | ) 77 | 78 | target_include_directories(butano PUBLIC 79 | "butano/include" 80 | "butano/hw/3rd_party/libtonc/include" 81 | ) 82 | target_include_directories(butano PRIVATE 83 | "butano/hw/3rd_party/libugba/include" 84 | "butano/hw/3rd_party/maxmod/include" 85 | ) 86 | target_compile_features(butano PUBLIC cxx_std_20) 87 | 88 | set(ARCH -mthumb -mthumb-interwork) 89 | set(CWARNINGS -Wall -Wextra -Wpedantic -Wshadow -Wundef -Wunused-parameter -Wmisleading-indentation -Wduplicated-cond 90 | -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wswitch-default -Wstack-usage=16384) 91 | set(CFLAGS ${CWARNINGS} -gdwarf-4 -O2 -mcpu=arm7tdmi -mtune=arm7tdmi -ffast-math -ffunction-sections -fdata-sections ${ARCH}) 92 | set(CPPWARNINGS -Wuseless-cast -Wnon-virtual-dtor -Woverloaded-virtual) 93 | 94 | target_compile_options(butano PRIVATE 95 | $<$:${ARCH} -x assembler-with-cpp> 96 | $<$:${CFLAGS}> 97 | $<$:${CFLAGS} ${CPPWARNINGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics -fuse-cxa-atexit> 98 | ) 99 | 100 | target_compile_definitions(butano PUBLIC 101 | BN_TOOLCHAIN_TAG="gba-toolchain" 102 | BN_EWRAM_BSS_SECTION=".sbss" 103 | BN_IWRAM_START=__iwram_start__ 104 | BN_IWRAM_TOP=__iwram_top 105 | BN_IWRAM_END=__fini_array_end 106 | BN_ROM_START=__start 107 | BN_ROM_END=__rom_end 108 | ) 109 | 110 | # Set IWRAM compile options 111 | get_target_property(iwramSources butano SOURCES) 112 | list(FILTER iwramSources INCLUDE REGEX ".+\\.bn_iwram\\..+") 113 | set_source_files_properties(${iwramSources} PROPERTIES COMPILE_FLAGS "-fno-lto -marm -mlong-calls") 114 | 115 | # Set EWRAM compile options 116 | get_target_property(ewramSources butano SOURCES) 117 | list(FILTER ewramSources INCLUDE REGEX ".+\\.bn_ewram\\..+") 118 | set_source_files_properties(${ewramSources} PROPERTIES COMPILE_FLAGS "-fno-lto") 119 | 120 | # Set no-flto compile options 121 | get_target_property(nofltoSources butano SOURCES) 122 | list(FILTER nofltoSources INCLUDE REGEX ".+\\.bn_noflto\\..+") 123 | set_source_files_properties(${nofltoSources} PROPERTIES COMPILE_FLAGS "-fno-lto") 124 | ]=]) 125 | endif() 126 | 127 | add_subdirectory("${BUTANO_DIR}" "${CMAKE_BINARY_DIR}/lib/butano" EXCLUDE_FROM_ALL) 128 | 129 | if(CMAKE_BIN2S_PROGRAM) 130 | set(bin2sCommand "${CMAKE_BIN2S_PROGRAM}") 131 | else() 132 | set(bin2sCommand "${CMAKE_COMMAND}" -P "${BIN2S_SCRIPT}" --) 133 | endif() 134 | 135 | function(add_butano_assets target) 136 | set(multiValueArgs 137 | AUDIO 138 | DMG_AUDIO 139 | GRAPHICS 140 | ) 141 | cmake_parse_arguments(ARGS "" "" "${multiValueArgs}" ${ARGN}) 142 | 143 | set(binaryDir "${CMAKE_CURRENT_BINARY_DIR}/butano_${target}_assets") 144 | 145 | # Add audio outputs 146 | if(ARGS_AUDIO) 147 | set(byproducts "${binaryDir}/_bn_audio_files_info.txt" "${binaryDir}/_bn_audio_soundbank.bin") 148 | set(outputs "${binaryDir}/_bn_audio_soundbank.s") 149 | set(headers 150 | "${binaryDir}/bn_music_items.h" "${binaryDir}/bn_music_items_info.h" 151 | "${binaryDir}/bn_sound_items.h" "${binaryDir}/bn_sound_items_info.h" 152 | ) 153 | endif() 154 | 155 | # Add dmg_audio outputs 156 | foreach(dmgAudio ${ARGS_DMG_AUDIO}) 157 | get_filename_component(extension "${dmgAudio}" EXT) 158 | if(extension STREQUAL ".json") 159 | continue() 160 | endif() 161 | 162 | get_filename_component(name "${dmgAudio}" NAME_WE) 163 | if(name) 164 | list(APPEND outputs "${binaryDir}/${name}_bn_dmg.c") 165 | endif() 166 | endforeach() 167 | 168 | # Add graphics outputs 169 | foreach(graphics ${ARGS_GRAPHICS}) 170 | get_filename_component(extension "${graphics}" EXT) 171 | if(extension STREQUAL ".json") 172 | continue() 173 | endif() 174 | 175 | get_filename_component(name "${graphics}" NAME_WE) 176 | if(name) 177 | list(APPEND outputs "${binaryDir}/${name}_bn_gfx.s") 178 | list(APPEND byproducts "${binaryDir}/_bn_${name}_graphics_file_info.txt") 179 | endif() 180 | #TODO: Support JSON file generation 181 | endforeach() 182 | 183 | if(NOT outputs AND NOT headers) 184 | message(FATAL_ERROR "add_butano_assets called with empty assets") 185 | endif() 186 | 187 | # Butano asset tool 188 | find_file(butano_assets_tool NAMES "butano_assets_tool.py" PATHS "${BUTANO_DIR}/butano/tools") 189 | add_custom_command( 190 | OUTPUT ${outputs} ${headers} 191 | BYPRODUCTS "${byproducts}" 192 | COMMAND "${CMAKE_COMMAND}" -E make_directory "${binaryDir}" 193 | COMMAND "${Python_EXECUTABLE}" "${butano_assets_tool}" 194 | --grit="${CMAKE_GRIT_PROGRAM}" 195 | --mmutil="${CMAKE_MMUTIL_PROGRAM}" 196 | --audio="${ARGS_AUDIO}" 197 | --dmg_audio="${ARGS_DMG_AUDIO}" 198 | --graphics="${ARGS_GRAPHICS}" 199 | --build="${binaryDir}" 200 | COMMAND ${bin2sCommand} "${binaryDir}/_bn_audio_soundbank.bin" > "${binaryDir}/_bn_audio_soundbank.s" 201 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 202 | ) 203 | 204 | add_library(${target} OBJECT ${outputs}) 205 | target_include_directories(${target} INTERFACE "${binaryDir}") 206 | endfunction() 207 | -------------------------------------------------------------------------------- /cmake/Modules/Findgba-hpp.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(FetchContent) 9 | 10 | if(EXISTS "${CMAKE_SYSTEM_LIBRARY_PATH}/gba-hpp/CMakeLists.txt" OR EXISTS "${CMAKE_BINARY_DIR}/lib/gba-hpp/CMakeLists.txt") 11 | add_subdirectory("${CMAKE_SYSTEM_LIBRARY_PATH}/gba-hpp" "${CMAKE_BINARY_DIR}/lib/gba-hpp" EXCLUDE_FROM_ALL) 12 | else() 13 | FetchContent_Declare(gba-hpp DOWNLOAD_EXTRACT_TIMESTAMP ON 14 | SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/gba-hpp" 15 | GIT_REPOSITORY "https://github.com/felixjones/gba-hpp.git" 16 | GIT_TAG "main" 17 | ) 18 | 19 | FetchContent_MakeAvailable(gba-hpp) 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/Modules/Findgbfs.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Provides the CMake function `add_gbfs_archive` for adding a gbfs archive target 4 | # 5 | # gbfs targets will also convert their `.gbfs` archive to a `.s` assembly file, available by linking with the target 6 | # The `GBFS_FILE` property can be used as a file dependency 7 | # 8 | # Example: 9 | # ```cmake 10 | # add_gbfs_archive(my_archive path/to/my/asset.bin path/to/another/file.txt) 11 | # target_link_libraries(my_executable PRIVATE my_archive) 12 | # get_target_property(archive_gbfs_path my_archive GBFS_FILE) 13 | # install(my_archive) 14 | # ``` 15 | # ```c 16 | # typedef unsigned short u16; 17 | # typedef unsigned int u32; 18 | # #include 19 | # extern const GBFS_FILE my_archive_gbfs[]; 20 | # ``` 21 | # 22 | # Copyright (C) 2021-2023 gba-toolchain contributors 23 | # For conditions of distribution and use, see copyright notice in LICENSE.md 24 | # 25 | #=============================================================================== 26 | 27 | enable_language(ASM) 28 | 29 | include(FetchContent) 30 | 31 | find_library(libgbfs gbfs PATHS "$ENV{DEVKITPRO}/gbfs" "${CMAKE_SYSTEM_LIBRARY_PATH}/gbfs" "${GBFS_DIR}" PATH_SUFFIXES lib) 32 | find_program(CMAKE_GBFS_PROGRAM gbfs gbfs.exe PATHS "$ENV{DEVKITPRO}/tools" "${CMAKE_SYSTEM_LIBRARY_PATH}/gbfs" "${GBFS_DIR}" PATH_SUFFIXES bin) 33 | find_program(CMAKE_BIN2S_PROGRAM bin2s bin2s.exe PATHS "$ENV{DEVKITPRO}/tools" "${CMAKE_SYSTEM_LIBRARY_PATH}/gbfs" "${GBFS_DIR}" PATH_SUFFIXES bin) 34 | 35 | if(NOT libgbfs OR NOT CMAKE_GBFS_PROGRAM OR NOT CMAKE_BIN2S_PROGRAM) 36 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/gbfs") 37 | 38 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 39 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 40 | cmake_minimum_required(VERSION 3.18) 41 | project(gbfs C) 42 | 43 | if(CMAKE_SYSTEM_NAME STREQUAL AdvancedGameBoy) 44 | add_library(gbfs STATIC "libgbfs.c") 45 | 46 | target_compile_options(gbfs PRIVATE 47 | $<$:-mthumb -O2 48 | -fomit-frame-pointer 49 | -ffunction-sections 50 | -fdata-sections 51 | -Wall 52 | -Wextra 53 | -Wpedantic 54 | -Wconversion 55 | -Wno-sign-conversion 56 | -Wno-stringop-truncation 57 | > 58 | ) 59 | 60 | if(CMAKE_PROJECT_NAME STREQUAL gbfs) 61 | install(TARGETS gbfs 62 | LIBRARY DESTINATION lib 63 | ) 64 | install(FILES "gbfs.h" 65 | DESTINATION include 66 | ) 67 | else() 68 | file(INSTALL "gbfs.h" DESTINATION "${SOURCE_DIR}/build/include") 69 | target_include_directories(gbfs INTERFACE "${SOURCE_DIR}/build/include") 70 | endif() 71 | else() 72 | add_executable(gbfs "tools/gbfs.c") 73 | add_executable(bin2s "tools/bin2s.c") 74 | 75 | if(MSVC) 76 | target_sources(gbfs PRIVATE "tools/djbasename.c") 77 | endif() 78 | 79 | install(TARGETS gbfs bin2s DESTINATION bin) 80 | endif() 81 | ]=]) 82 | 83 | FetchContent_Declare(gbfs_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 84 | PREFIX "${SOURCE_DIR}" 85 | TMP_DIR "${SOURCE_DIR}/temp" 86 | STAMP_DIR "${SOURCE_DIR}/stamp" 87 | SOURCE_DIR "${SOURCE_DIR}/source" 88 | # Download 89 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 90 | URL "http://pineight.com/gba/gbfs.zip" 91 | URL_MD5 "8cb0dd8e1ff0405071e2a0c58c0f76e2" 92 | # Update 93 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy_if_different 94 | "${SOURCE_DIR}/temp/CMakeLists.txt" 95 | "${SOURCE_DIR}/source/CMakeLists.txt" 96 | ) 97 | 98 | if(NOT libgbfs) 99 | FetchContent_MakeAvailable(gbfs_proj) 100 | find_library(libgbfs gbfs PATHS "${SOURCE_DIR}/build") 101 | endif() 102 | 103 | if(NOT CMAKE_GBFS_PROGRAM OR NOT CMAKE_BIN2S_PROGRAM) 104 | FetchContent_GetProperties(gbfs_proj) 105 | if(NOT gbfs_proj_POPULATED) 106 | FetchContent_Populate(gbfs_proj) 107 | endif() 108 | 109 | if(CMAKE_HOST_WIN32) 110 | find_program(CMAKE_GBFS_PROGRAM gbfs PATHS "${SOURCE_DIR}/source/tools") 111 | find_program(CMAKE_BIN2S_PROGRAM bin2s PATHS "${SOURCE_DIR}/source/tools") 112 | endif() 113 | endif() 114 | 115 | if(NOT CMAKE_GBFS_PROGRAM OR NOT CMAKE_BIN2S_PROGRAM) 116 | # Configure 117 | execute_process( 118 | COMMAND ${CMAKE_COMMAND} -S . -B "${SOURCE_DIR}/build/tools" 119 | WORKING_DIRECTORY "${SOURCE_DIR}/source" 120 | RESULT_VARIABLE cmakeResult 121 | ) 122 | 123 | if(cmakeResult EQUAL "1") 124 | message(WARNING "Failed to configure gbfs (do you have a host compiler installed?)") 125 | else() 126 | # Build 127 | execute_process( 128 | COMMAND ${CMAKE_COMMAND} --build tools --config Release 129 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 130 | RESULT_VARIABLE cmakeResult 131 | ) 132 | 133 | if(cmakeResult EQUAL "1") 134 | message(WARNING "Failed to build gbfs") 135 | else() 136 | # Install 137 | execute_process( 138 | COMMAND ${CMAKE_COMMAND} --install tools --prefix "${SOURCE_DIR}" --config Release 139 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 140 | RESULT_VARIABLE cmakeResult 141 | ) 142 | 143 | if(cmakeResult EQUAL "1") 144 | message(WARNING "Failed to install gbfs") 145 | else() 146 | find_program(CMAKE_GBFS_PROGRAM gbfs PATHS "${SOURCE_DIR}/bin") 147 | find_program(CMAKE_BIN2S_PROGRAM bin2s PATHS "${SOURCE_DIR}/bin") 148 | endif() 149 | endif() 150 | endif() 151 | endif() 152 | endif() 153 | 154 | if(libgbfs AND NOT TARGET gbfs) 155 | add_library(gbfs STATIC IMPORTED) 156 | set_property(TARGET gbfs PROPERTY IMPORTED_LOCATION "${libgbfs}") 157 | 158 | get_filename_component(INCLUDE_PATH "${libgbfs}" DIRECTORY) 159 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 160 | target_include_directories(gbfs INTERFACE "${INCLUDE_PATH}/include") 161 | endif() 162 | 163 | if(NOT CMAKE_GBFS_PROGRAM) 164 | message(WARNING "gbfs not found: Please set `-DCMAKE_GBFS_PROGRAM:FILEPATH=`") 165 | endif() 166 | 167 | if(NOT CMAKE_BIN2S_PROGRAM) 168 | message(WARNING "bin2s not found: Please set `-DCMAKE_BIN2S_PROGRAM:FILEPATH=`") 169 | endif() 170 | 171 | function(add_gbfs_archive target) 172 | set(ASSETS $>) 173 | 174 | add_custom_command( 175 | OUTPUT ${target}.gbfs ${target}.s 176 | COMMAND "${CMAKE_GBFS_PROGRAM}" "${CMAKE_CURRENT_BINARY_DIR}/${target}.gbfs" ${ASSETS} 177 | COMMAND "${CMAKE_BIN2S_PROGRAM}" "${CMAKE_CURRENT_BINARY_DIR}/${target}.gbfs" > "${CMAKE_CURRENT_BINARY_DIR}/${target}.s" 178 | DEPENDS ${ASSETS} 179 | VERBATIM 180 | COMMAND_EXPAND_LISTS 181 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 182 | ) 183 | 184 | add_library(${target} OBJECT ${target}.s) 185 | 186 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}.gbfs" DESTINATION .) 187 | 188 | set_target_properties(${target} PROPERTIES 189 | ASSETS "${ARGN}" 190 | GBFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/${target}.gbfs" 191 | ) 192 | endfunction() 193 | 194 | unset(libgbfs CACHE) 195 | -------------------------------------------------------------------------------- /cmake/Modules/Findgbt-player.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | enable_language(ASM C) 9 | 10 | include(FetchContent) 11 | 12 | find_library(libgbt_player gbt_player PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/gbt_player" "${GBT_PLAYER_DIR}" PATH_SUFFIXES lib) 13 | 14 | if(NOT libgbt_player) 15 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/gbt_player") 16 | 17 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 18 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 19 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 20 | cmake_minimum_required(VERSION 3.18) 21 | project(gbt_player C) 22 | 23 | add_library(gbt-player STATIC "gba/gbt_player/gbt_player.c") 24 | 25 | target_compile_options(gbt-player PRIVATE 26 | $<$:-mthumb -O2 27 | -fomit-frame-pointer 28 | -ffunction-sections 29 | -fdata-sections 30 | -Wall 31 | -Wextra 32 | -Wpedantic 33 | -Wconversion 34 | -Wno-sign-conversion 35 | -Wno-stringop-truncation 36 | > 37 | ) 38 | 39 | if(CMAKE_PROJECT_NAME STREQUAL gbt_player) 40 | install(TARGETS gbt-player 41 | LIBRARY DESTINATION lib 42 | ) 43 | install(FILES "gba/gbt_player/gbt_hardware.h" "gba/gbt_player/gbt_player.h" 44 | DESTINATION include 45 | ) 46 | else() 47 | file(INSTALL "gba/gbt_player/gbt_hardware.h" "gba/gbt_player/gbt_player.h" DESTINATION "${SOURCE_DIR}/build/include") 48 | target_include_directories(gbt-player INTERFACE "${SOURCE_DIR}/build/include") 49 | endif() 50 | ]=]) 51 | 52 | ExternalProject_Add(gbt_player_proj 53 | PREFIX "${SOURCE_DIR}" 54 | TMP_DIR "${SOURCE_DIR}/temp" 55 | STAMP_DIR "${SOURCE_DIR}/stamp" 56 | # Download 57 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 58 | GIT_REPOSITORY "https://github.com/AntonioND/gbt-player.git" 59 | GIT_TAG "master" 60 | # Update 61 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy_if_different 62 | "${SOURCE_DIR}/temp/CMakeLists.txt" 63 | "${SOURCE_DIR}/source/CMakeLists.txt" 64 | # Configure 65 | SOURCE_DIR "${SOURCE_DIR}/source" 66 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 67 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 68 | # Build 69 | BINARY_DIR "${SOURCE_DIR}/build" 70 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 71 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libgbt-player.a" 72 | # Install 73 | INSTALL_DIR "${SOURCE_DIR}" 74 | ) 75 | 76 | add_library(gbt-player STATIC IMPORTED) 77 | add_dependencies(gbt-player gbt_player_proj) 78 | set_property(TARGET gbt-player PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libgbt-player.a") 79 | target_include_directories(gbt-player INTERFACE "${SOURCE_DIR}/include") 80 | else() 81 | add_library(gbt-player STATIC IMPORTED) 82 | set_property(TARGET gbt-player PROPERTY IMPORTED_LOCATION "${libgbt_player}") 83 | 84 | get_filename_component(INCLUDE_PATH "${libgbt_player}" DIRECTORY) 85 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 86 | target_include_directories(gbt-player INTERFACE "${INCLUDE_PATH}/include") 87 | endif() 88 | 89 | unset(libgbt_player CACHE) 90 | 91 | # gbt-player tools 92 | if(NOT Python_EXECUTABLE) 93 | find_package(Python COMPONENTS Interpreter REQUIRED) 94 | endif() 95 | 96 | find_file(s3m2gbt NAMES "gba/s3m2gbt/s3m2gbt.py" PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/gbt_player" "${GBT_PLAYER_DIR}" PATH_SUFFIXES source NO_CACHE) 97 | find_file(mod2gbt NAMES "gba/mod2gbt/mod2gbt.py" PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/gbt_player" "${GBT_PLAYER_DIR}" PATH_SUFFIXES source NO_CACHE) 98 | function(add_gbt_assets target) 99 | foreach(input ${ARGN}) 100 | get_filename_component(name ${input} NAME_WE) 101 | get_filename_component(ext ${input} LAST_EXT) 102 | set(output "${name}.c") 103 | 104 | if(ext STREQUAL ".s3m") 105 | add_custom_command( 106 | OUTPUT "${output}" 107 | COMMAND "${CMAKE_COMMAND}" -E env "${Python_EXECUTABLE}" "${s3m2gbt}" 108 | --input "${input}" 109 | --name "${target}_${name}" 110 | --output "${CMAKE_CURRENT_BINARY_DIR}/${output}" 111 | --instruments 112 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 113 | ) 114 | elseif(ext STREQUAL ".mod") 115 | add_custom_command( 116 | OUTPUT "${output}" 117 | COMMAND "${CMAKE_COMMAND}" -E env "${Python_EXECUTABLE}" "${mod2gbt}" 118 | "${CMAKE_CURRENT_SOURCE_DIR}/${input}" "${target}_${name}" 119 | COMMAND "${CMAKE_COMMAND}" -E rename "${target}_${output}" "${output}" 120 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 121 | ) 122 | else() 123 | message(FATAL_ERROR "${input} must be .s3m or .mod format") 124 | endif() 125 | list(APPEND outputs ${output}) 126 | endforeach() 127 | 128 | add_library(${target} OBJECT ${outputs}) 129 | endfunction() 130 | 131 | find_file(s3msplit NAMES "gba/s3msplit/s3msplit.py" PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/gbt_player" "${GBT_PLAYER_DIR}" PATH_SUFFIXES source NO_CACHE) 132 | function(add_gbt_maxmod_assets target) 133 | find_package(maxmod REQUIRED) 134 | 135 | foreach(input ${ARGN}) 136 | get_filename_component(name ${input} NAME_WE) 137 | get_filename_component(ext ${input} LAST_EXT) 138 | set(output "${name}.c") 139 | 140 | if(ext STREQUAL ".s3m") 141 | add_custom_command( 142 | OUTPUT "${output}" "${name}_dma.s3m" 143 | BYPRODUCTS "${name}_psg.s3m" 144 | COMMAND "${CMAKE_COMMAND}" -E env "${Python_EXECUTABLE}" "${s3msplit}" 145 | --input "${input}" 146 | --psg "${CMAKE_CURRENT_BINARY_DIR}/${name}_psg.s3m" 147 | --dma "${CMAKE_CURRENT_BINARY_DIR}/${name}_dma.s3m" 148 | COMMAND "${CMAKE_COMMAND}" -E env "${Python_EXECUTABLE}" "${s3m2gbt}" 149 | --input "${CMAKE_CURRENT_BINARY_DIR}/${name}_psg.s3m" 150 | --name "${target}_${name}" 151 | --output "${CMAKE_CURRENT_BINARY_DIR}/${output}" 152 | --instruments 153 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 154 | ) 155 | list(APPEND outputs ${output}) 156 | list(APPEND dma "${name}_dma.s3m") 157 | else() 158 | message(FATAL_ERROR "${input} must be .s3m format") 159 | endif() 160 | endforeach() 161 | 162 | if(CMAKE_BIN2S_PROGRAM) 163 | set(bin2sCommand "${CMAKE_BIN2S_PROGRAM}") 164 | else() 165 | set(bin2sCommand "${CMAKE_COMMAND}" -P "${BIN2S_SCRIPT}" --) 166 | endif() 167 | 168 | add_custom_command( 169 | OUTPUT "${target}.s" "soundbank/${target}.h" 170 | BYPRODUCTS "${target}.bin" 171 | DEPENDS ${dma} 172 | COMMAND "${CMAKE_COMMAND}" -E make_directory "soundbank" 173 | COMMAND "${CMAKE_MMUTIL_PROGRAM}" -o${target}.bin -hsoundbank/${target}.h ${dma} 174 | COMMAND ${bin2sCommand} "${target}.bin" > "${target}.s" 175 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 176 | ) 177 | 178 | add_library(${target} OBJECT ${outputs} "${target}.s") 179 | target_include_directories(${target} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) 180 | endfunction() 181 | -------------------------------------------------------------------------------- /cmake/Modules/Findgrit.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Provides the CMake functions for adding a grit assets target: 4 | # `add_grit_tilemap`, `add_grit_sprite`, and `add_grit_bitmap` 5 | # 6 | # Copyright (C) 2021-2023 gba-toolchain contributors 7 | # For conditions of distribution and use, see copyright notice in LICENSE.md 8 | # 9 | #=============================================================================== 10 | 11 | enable_language(ASM C) 12 | 13 | include(FetchContent) 14 | 15 | find_program(CMAKE_GRIT_PROGRAM grit grit.exe PATHS "$ENV{DEVKITPRO}/tools" "${CMAKE_SYSTEM_LIBRARY_PATH}/grit" "${GRIT_DIR}" PATH_SUFFIXES bin) 16 | 17 | if(NOT CMAKE_GRIT_PROGRAM) 18 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/grit") 19 | 20 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 21 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 22 | cmake_minimum_required(VERSION 3.18) 23 | project(grit VERSION 0.9.2 LANGUAGES CXX) 24 | 25 | if(TOOLCHAIN_MODULE_PATH) 26 | list(APPEND CMAKE_MODULE_PATH ${TOOLCHAIN_MODULE_PATH}) 27 | endif() 28 | find_package(FreeImage REQUIRED) 29 | 30 | add_library(cldib STATIC 31 | cldib/cldib_adjust.cpp 32 | cldib/cldib_conv.cpp 33 | cldib/cldib_core.cpp 34 | cldib/cldib_tmap.cpp 35 | cldib/cldib_tools.cpp 36 | cldib/cldib_wu.cpp 37 | ) 38 | target_include_directories(cldib PUBLIC cldib) 39 | 40 | add_library(libgrit STATIC 41 | libgrit/cprs.cpp 42 | libgrit/cprs_huff.cpp 43 | libgrit/cprs_lz.cpp 44 | libgrit/cprs_rle.cpp 45 | libgrit/grit_core.cpp 46 | libgrit/grit_misc.cpp 47 | libgrit/grit_prep.cpp 48 | libgrit/grit_shared.cpp 49 | libgrit/grit_xp.cpp 50 | libgrit/logger.cpp 51 | libgrit/pathfun.cpp 52 | ) 53 | set_target_properties(libgrit PROPERTIES PREFIX "") 54 | target_include_directories(libgrit PUBLIC libgrit .) 55 | target_link_libraries(libgrit PUBLIC cldib) 56 | target_compile_definitions(libgrit PUBLIC PACKAGE_VERSION="${CMAKE_PROJECT_VERSION}") 57 | 58 | add_executable(grit 59 | srcgrit/cli.cpp 60 | srcgrit/grit_main.cpp 61 | extlib/fi.cpp 62 | ) 63 | target_include_directories(grit PRIVATE extlib) 64 | target_link_libraries(grit PRIVATE 65 | libgrit 66 | freeimage::FreeImage 67 | $<$>:m> 68 | ) 69 | 70 | install(TARGETS grit DESTINATION bin) 71 | ]=]) 72 | 73 | FetchContent_Declare(grit_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 74 | PREFIX "${SOURCE_DIR}" 75 | TMP_DIR "${SOURCE_DIR}/temp" 76 | STAMP_DIR "${SOURCE_DIR}/stamp" 77 | SOURCE_DIR "${SOURCE_DIR}/source" 78 | # Download 79 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 80 | GIT_REPOSITORY "https://github.com/devkitPro/grit.git" 81 | GIT_TAG "master" 82 | # Update 83 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy_if_different 84 | "${SOURCE_DIR}/temp/CMakeLists.txt" 85 | "${SOURCE_DIR}/source/CMakeLists.txt" 86 | ) 87 | 88 | FetchContent_Populate(grit_proj) 89 | 90 | # Configure 91 | execute_process( 92 | COMMAND "${CMAKE_COMMAND}" -S . -B "${SOURCE_DIR}/build" 93 | "-DTOOLCHAIN_MODULE_PATH=${CMAKE_MODULE_PATH}" 94 | "-DTOOLCHAIN_LIBRARY_PATH=${CMAKE_SYSTEM_LIBRARY_PATH}" 95 | WORKING_DIRECTORY "${SOURCE_DIR}/source" 96 | RESULT_VARIABLE cmakeResult 97 | ) 98 | 99 | if(cmakeResult EQUAL "1") 100 | message(WARNING "Failed to configure grit") 101 | else() 102 | # Build 103 | execute_process( 104 | COMMAND "${CMAKE_COMMAND}" --build . --config Release 105 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 106 | RESULT_VARIABLE cmakeResult 107 | ) 108 | 109 | if(cmakeResult EQUAL "1") 110 | message(WARNING "Failed to build grit") 111 | else() 112 | # Install 113 | execute_process( 114 | COMMAND ${CMAKE_COMMAND} --install . --prefix "${SOURCE_DIR}" --config Release 115 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 116 | RESULT_VARIABLE cmakeResult 117 | ) 118 | 119 | if(cmakeResult EQUAL "1") 120 | message(WARNING "Failed to install grit") 121 | else() 122 | find_program(CMAKE_GRIT_PROGRAM grit PATHS "${SOURCE_DIR}/bin") 123 | endif() 124 | endif() 125 | endif() 126 | endif() 127 | 128 | if(NOT CMAKE_GRIT_PROGRAM) 129 | message(WARNING "grit not found: Please set `-DCMAKE_GRIT_PROGRAM:FILEPATH=`") 130 | endif() 131 | 132 | function(add_grit_tilemap target type) 133 | file(RELATIVE_PATH inpath "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") 134 | set(outpath "${CMAKE_CURRENT_BINARY_DIR}") 135 | 136 | set(oneValueArgs 137 | SHARED_PREFIX # File to use for shared output (default is target name when sharing is used) 138 | LOG_LEVEL # 1, 2, or 3 (default is 1) 139 | DATA_TYPE # Default data type (individual options can override this) u8, u16, or u32 140 | OPTIONS_FILE # File to read in additional options 141 | ) 142 | set(multiValueArgs 143 | GRAPHICS 144 | PALETTE 145 | MAP 146 | -- 147 | ) 148 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 149 | grit_parse_arguments_graphics(ARGS_GFX optGfx ${ARGS_GRAPHICS}) 150 | grit_parse_arguments_palette(ARGS_PAL optPal ${ARGS_PALETTE}) 151 | grit_parse_arguments_map(ARGS_MAP optMap ${ARGS_MAP}) 152 | 153 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_GFX_UNPARSED_ARGUMENTS}) 154 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_PAL_UNPARSED_ARGUMENTS}) 155 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_MAP_UNPARSED_ARGUMENTS}) 156 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_--}) 157 | set(ARGN ${ARGS_UNPARSED_ARGUMENTS}) 158 | 159 | # Tilemap options 160 | 161 | set(opts "-gt") # Tilemap mode 162 | 163 | if(NOT ARGS_GFX_BIT_DEPTH) 164 | list(APPEND opts "-gB4") # Default to 4bpp tile graphics 165 | endif() 166 | if(NOT ARGS_MAP_LAYOUT) 167 | list(APPEND opts "-mLs") # Default to SBB layout 168 | endif() 169 | if(NOT ARGS_MAP_OPTIMIZE) 170 | if(ARGS_GFX_BIT_DEPTH EQUAL 8) 171 | if(ARGS_MAP_LAYOUT STREQUAL AFFINE) 172 | list(APPEND opts "-mRa") # Optimise for affine 173 | else() 174 | list(APPEND opts "-mR8") # Optimise for 8bpp 175 | endif() 176 | elseif(NOT ARGS_GFX_BIT_DEPTH OR ARGS_GFX_BIT_DEPTH EQUAL 4) 177 | list(APPEND opts "-mR4") # Optimise for 4bpp 178 | endif() 179 | endif() 180 | 181 | if(type STREQUAL C) 182 | set(suffix ".c") 183 | list(APPEND opts "-ftc") 184 | elseif(type STREQUAL ASM) 185 | set(suffix ".s") 186 | list(APPEND opts "-fts") 187 | elseif(type STREQUAL BIN OR type STREQUAL BINARY) 188 | set(palsuffix ".pal.bin") 189 | set(imgsuffix ".img.bin") 190 | set(mapsuffix ".map.bin") 191 | list(APPEND opts "-ftb" "-fh!") 192 | elseif(type STREQUAL GBFS) 193 | set(suffix ".gbfs") 194 | list(APPEND opts "-ftg" "-fh!") 195 | else() 196 | message(FATAL_ERROR "Unknown grit output type '${type}'") 197 | endif() 198 | 199 | # Common file options 200 | 201 | if(ARGS_SHARED_PREFIX) 202 | list(APPEND opts "-O${ARGS_SHARED_PREFIX}") 203 | elseif(ARGS_GFX_SHARED OR ARGS_PAL_SHARED) 204 | list(APPEND opts "-O${target}") 205 | endif() 206 | 207 | if(ARGS_LOG_LEVEL EQUAL 1) 208 | list(APPEND opts "-W1") 209 | elseif(ARGS_LOG_LEVEL EQUAL 2) 210 | list(APPEND opts "-W2") 211 | elseif(ARGS_LOG_LEVEL EQUAL 3) 212 | list(APPEND opts "-W3") 213 | elseif(ARGS_LOG_LEVEL) 214 | message(WARNING "Invalid grit log level '${ARGS_LOG_LEVEL}'. Must be '1', '2', or '3'.") 215 | endif() 216 | 217 | if(ARGS_DATA_TYPE MATCHES "^[uU]8$") 218 | list(APPEND opts "-U8") 219 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]16$") 220 | list(APPEND opts "-U16") 221 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]32$") 222 | list(APPEND opts "-U32") 223 | elseif(ARGS_DATA_TYPE) 224 | message(WARNING "Invalid grit data type '${ARGS_DATA_TYPE}'. Must be 'u8', 'u16', or 'u32'.") 225 | endif() 226 | 227 | if(ARGS_COMPRESSION STREQUAL OFF OR ARGS_COMPRESSION STREQUAL NONE) 228 | list(APPEND opts "-Z!") 229 | elseif(ARGS_COMPRESSION STREQUAL LZ77) 230 | list(APPEND opts "-Zl") 231 | elseif(ARGS_COMPRESSION STREQUAL HUFF OR ARGS_COMPRESSION STREQUAL HUFFMAN) 232 | list(APPEND opts "-Zh") 233 | elseif(ARGS_COMPRESSION STREQUAL RLE OR ARGS_COMPRESSION STREQUAL RUN_LENGTH_ENCODING) 234 | list(APPEND opts "-Zr") 235 | elseif(ARGS_COMPRESSION) 236 | message(WARNING "Invalid grit compression type '${ARGS_COMPRESSION}'. Must be 'OFF', 'LZ77', 'HUFF', or 'RLE'.") 237 | endif() 238 | 239 | list(APPEND opts ${optGfx} ${optPal} ${optMap}) 240 | 241 | if(ARGS_OPTIONS_FILE) 242 | if(IS_ABSOLUTE ${ARGS_OPTIONS_FILE}) 243 | list(APPEND opts "-ff${ARGS_OPTIONS_FILE}") 244 | else() 245 | list(APPEND opts "-ff${inpath}/${ARGS_OPTIONS_FILE}") 246 | endif() 247 | endif() 248 | 249 | # Setup the output files 250 | 251 | if(suffix) 252 | macro(append_output prefix operation) 253 | list(APPEND output "${outpath}/${prefix}${suffix}") 254 | if(type STREQUAL C OR type STREQUAL ASM) 255 | list(APPEND output "${outpath}/${prefix}.h") # TODO : Header exclude support? 256 | endif() 257 | endmacro() 258 | else() 259 | macro(append_output prefix operation) 260 | if(NOT ARGS_MAP_EXCLUDE AND ${operation} ARGS_MAP_SHARED) 261 | list(APPEND output "${outpath}/${prefix}${mapsuffix}") 262 | endif() 263 | if(NOT ARGS_PAL_EXCLUDE AND ${operation} ARGS_PAL_SHARED) 264 | list(APPEND output "${outpath}/${prefix}${palsuffix}") 265 | endif() 266 | if(NOT ARGS_GFX_EXCLUDE AND ${operation} ARGS_GFX_SHARED) 267 | list(APPEND output "${outpath}/${prefix}${imgsuffix}") 268 | endif() 269 | endmacro() 270 | endif() 271 | 272 | if(ARGS_SHARED_PREFIX) 273 | append_output(${ARGS_SHARED_PREFIX} "") 274 | elseif(ARGS_GFX_SHARED OR ARGS_PAL_SHARED OR ARGS_MAP_SHARED) 275 | append_output(${target} "") 276 | endif() 277 | 278 | foreach(arg ${ARGN}) 279 | if(arg MATCHES "[$][<]TARGET_[A-Z_]+[:].+[>]") 280 | message(WARNING "Tried to set genex '${arg}' as an output for '${target}'") 281 | continue() 282 | endif() 283 | if(arg MATCHES "[$][<][A-Z_]+[:].+[>]") 284 | list(APPEND input "${arg}") # Copy any valid generator expression 285 | else() 286 | if(IS_ABSOLUTE ${arg}) 287 | list(APPEND input "${arg}") 288 | else() 289 | list(APPEND input "${inpath}/${arg}") 290 | endif() 291 | # Parse the file and expected output types to produce output names 292 | get_filename_component(arg "${arg}" NAME_WE) 293 | append_output(${arg} NOT) 294 | endif() 295 | endforeach() 296 | 297 | # Setup the grit command 298 | 299 | add_custom_command( 300 | OUTPUT ${output} 301 | COMMAND "${CMAKE_GRIT_PROGRAM}" ${input} ${opts} 302 | DEPENDS ${input} 303 | VERBATIM 304 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 305 | ) 306 | 307 | # Setup the target 308 | 309 | if(type STREQUAL C OR type STREQUAL ASM) 310 | add_library(${target} OBJECT ${output}) 311 | target_include_directories(${target} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") 312 | else() 313 | add_custom_target(${target} DEPENDS ${output}) 314 | set_target_properties(${target} PROPERTIES OBJECTS "${output}") 315 | endif() 316 | endfunction() 317 | 318 | function(add_grit_sprite target type) 319 | set(args MAP EXCLUDE ${ARGN}) 320 | add_grit_tilemap(${target} ${type} ${args}) 321 | endfunction() 322 | 323 | function(add_grit_bitmap target type) 324 | file(RELATIVE_PATH inpath "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") 325 | set(outpath "${CMAKE_CURRENT_BINARY_DIR}") 326 | 327 | set(oneValueArgs 328 | SHARED_PREFIX # File to use for shared output (default is target name when sharing is used) 329 | LOG_LEVEL # 1, 2, or 3 (default is 1) 330 | DATA_TYPE # Default data type (individual options can override this) u8, u16, or u32 331 | COMPRESSION # Default compression type (individual options can override this) 332 | OPTIONS_FILE # File to read in additional options 333 | ) 334 | set(multiValueArgs 335 | GRAPHICS 336 | PALETTE 337 | -- 338 | ) 339 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 340 | grit_parse_arguments_graphics(ARGS_GFX optGfx ${ARGS_GRAPHICS}) 341 | grit_parse_arguments_palette(ARGS_PAL optPal ${ARGS_PALETTE}) 342 | 343 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_GFX_UNPARSED_ARGUMENTS}) 344 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_PAL_UNPARSED_ARGUMENTS}) 345 | list(APPEND ARGS_UNPARSED_ARGUMENTS ${ARGS_--}) 346 | set(ARGN ${ARGS_UNPARSED_ARGUMENTS}) 347 | 348 | # Bitmap options 349 | 350 | set(opts "-gb") # Bitmap mode 351 | 352 | if(type STREQUAL C) 353 | set(suffix ".c") 354 | list(APPEND opts "-ftc") 355 | elseif(type STREQUAL ASM) 356 | set(suffix ".s") 357 | list(APPEND opts "-fts") 358 | elseif(type STREQUAL BIN OR type STREQUAL BINARY) 359 | set(palsuffix ".pal.bin") 360 | set(imgsuffix ".img.bin") 361 | list(APPEND opts "-ftb" "-fh!") 362 | elseif(type STREQUAL GBFS) 363 | set(suffix ".gbfs") 364 | list(APPEND opts "-ftg" "-fh!") 365 | else() 366 | message(FATAL_ERROR "Unknown grit output type '${type}'") 367 | endif() 368 | 369 | # Common file options 370 | 371 | if(ARGS_SHARED_PREFIX) 372 | list(APPEND opts "-O${ARGS_SHARED_PREFIX}") 373 | elseif(ARGS_GFX_SHARED OR ARGS_PAL_SHARED) 374 | list(APPEND opts "-O${target}") 375 | endif() 376 | 377 | if(ARGS_LOG_LEVEL EQUAL 1) 378 | list(APPEND opts "-W1") 379 | elseif(ARGS_LOG_LEVEL EQUAL 2) 380 | list(APPEND opts "-W2") 381 | elseif(ARGS_LOG_LEVEL EQUAL 3) 382 | list(APPEND opts "-W3") 383 | elseif(ARGS_LOG_LEVEL) 384 | message(WARNING "Invalid grit log level '${ARGS_LOG_LEVEL}'. Must be '1', '2', or '3'.") 385 | endif() 386 | 387 | if(ARGS_DATA_TYPE MATCHES "^[uU]8$") 388 | list(APPEND opts "-U8") 389 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]16$") 390 | list(APPEND opts "-U16") 391 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]32$") 392 | list(APPEND opts "-U32") 393 | elseif(ARGS_DATA_TYPE) 394 | message(WARNING "Invalid grit data type '${ARGS_DATA_TYPE}'. Must be 'u8', 'u16', or 'u32'.") 395 | endif() 396 | 397 | if(ARGS_COMPRESSION STREQUAL OFF OR ARGS_COMPRESSION STREQUAL NONE) 398 | list(APPEND opts "-Z!") 399 | elseif(ARGS_COMPRESSION STREQUAL LZ77) 400 | list(APPEND opts "-Zl") 401 | elseif(ARGS_COMPRESSION STREQUAL HUFF OR ARGS_COMPRESSION STREQUAL HUFFMAN) 402 | list(APPEND opts "-Zh") 403 | elseif(ARGS_COMPRESSION STREQUAL RLE OR ARGS_COMPRESSION STREQUAL RUN_LENGTH_ENCODING) 404 | list(APPEND opts "-Zr") 405 | elseif(ARGS_COMPRESSION) 406 | message(WARNING "Invalid grit compression type '${ARGS_COMPRESSION}'. Must be 'OFF', 'LZ77', 'HUFF', or 'RLE'.") 407 | endif() 408 | 409 | list(APPEND opts ${optGfx} ${optPal}) 410 | 411 | if(ARGS_OPTIONS_FILE) 412 | if(IS_ABSOLUTE ARGS_OPTIONS_FILE) 413 | list(APPEND opts "-ff${ARGS_OPTIONS_FILE}") 414 | else() 415 | list(APPEND opts "-ff${inpath}/${ARGS_OPTIONS_FILE}") 416 | endif() 417 | endif() 418 | 419 | # Setup the output files 420 | 421 | if(suffix) 422 | macro(append_output prefix operation) 423 | list(APPEND output "${outpath}/${prefix}${suffix}") 424 | if(type STREQUAL C OR type STREQUAL ASM) 425 | list(APPEND output "${outpath}/${prefix}.h") # TODO : Header exclude support? 426 | endif() 427 | endmacro() 428 | else() 429 | macro(append_output prefix operation) 430 | if(NOT ARGS_PAL_EXCLUDE AND ${operation} ARGS_PAL_SHARED) 431 | list(APPEND output "${outpath}/${prefix}${palsuffix}") 432 | endif() 433 | if(NOT ARGS_GFX_EXCLUDE AND ${operation} ARGS_GFX_SHARED) 434 | list(APPEND output "${outpath}/${prefix}${imgsuffix}") 435 | endif() 436 | endmacro() 437 | endif() 438 | 439 | if(ARGS_SHARED_PREFIX) 440 | append_output(${ARGS_SHARED_PREFIX} "") 441 | elseif(ARGS_GFX_SHARED OR ARGS_PAL_SHARED) 442 | append_output(${target} "") 443 | endif() 444 | 445 | foreach(arg ${ARGN}) 446 | if(arg MATCHES "[$][<]TARGET_[A-Z_]+[:].+[>]") 447 | message(WARNING "Tried to set genex '${arg}' as an output for '${target}'") 448 | continue() 449 | endif() 450 | if(arg MATCHES "[$][<][A-Z_]+[:].+[>]") 451 | list(APPEND input "${arg}") # Copy any valid generator expression 452 | else() 453 | if(IS_ABSOLUTE ${arg}) 454 | list(APPEND input "${arg}") 455 | else() 456 | list(APPEND input "${inpath}/${arg}") 457 | endif() 458 | # Parse the file and expected output types to produce output names 459 | get_filename_component(arg "${arg}" NAME_WE) 460 | append_output(${arg} NOT) 461 | endif() 462 | endforeach() 463 | 464 | # Setup the grit command 465 | 466 | add_custom_command( 467 | OUTPUT ${output} 468 | COMMAND "${CMAKE_GRIT_PROGRAM}" ${input} ${opts} 469 | DEPENDS ${input} 470 | VERBATIM 471 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 472 | ) 473 | 474 | # Setup the target 475 | 476 | if(type STREQUAL C OR type STREQUAL ASM) 477 | add_library(${target} OBJECT ${output}) 478 | target_include_directories(${target} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") 479 | else() 480 | add_custom_target(${target} DEPENDS ${output}) 481 | set_target_properties(${target} PROPERTIES OBJECTS "${output}") 482 | endif() 483 | endfunction() 484 | 485 | macro(grit_copy_arguments dest source arguments) 486 | foreach(arg ${arguments}) 487 | set(${dest}_${arg} ${${source}_${arg}} PARENT_SCOPE) 488 | endforeach() 489 | endmacro() 490 | 491 | macro(grit_copy_parsed_arguments dest source options oneValueArgs multiValueArgs) 492 | grit_copy_arguments(${dest} ${source} "${options}") 493 | grit_copy_arguments(${dest} ${source} "${oneValueArgs}") 494 | grit_copy_arguments(${dest} ${source} "${multiValueArgs}") 495 | set(${dest}_UNPARSED_ARGUMENTS ${${source}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 496 | endmacro() 497 | 498 | function(grit_parse_arguments_common prefix x outOptions outArgs) 499 | set(options 500 | EXCLUDE # Don't generate this type (overrides everything else) 501 | SHARED # Should this use the shared file (see SHARED_PREFIX) 502 | ) 503 | set(oneValueArgs 504 | DATA_TYPE # u8, u16, or u32 505 | COMPRESSION 506 | ) 507 | cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "" ${ARGN}) 508 | 509 | if(ARGS_EXCLUDE) 510 | list(APPEND opts "-${x}!") 511 | endif() 512 | if(ARGS_SHARED) 513 | list(APPEND opts "-${x}S") 514 | endif() 515 | if(ARGS_DATA_TYPE MATCHES "^[uU]8$") 516 | list(APPEND opts "-${x}u8") 517 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]16$") 518 | list(APPEND opts "-${x}u16") 519 | elseif(ARGS_DATA_TYPE MATCHES "^[uU]32$") 520 | list(APPEND opts "-${x}u32") 521 | elseif(ARGS_DATA_TYPE) 522 | message(WARNING "Invalid grit data type '${ARGS_DATA_TYPE}'. Must be 'u8', 'u16', or 'u32'.") 523 | endif() 524 | if(ARGS_COMPRESSION STREQUAL OFF OR ARGS_COMPRESSION STREQUAL NONE) 525 | list(APPEND opts "-${x}z!") 526 | elseif(ARGS_COMPRESSION STREQUAL LZ77) 527 | list(APPEND opts "-${x}zl") 528 | elseif(ARGS_COMPRESSION STREQUAL HUFF OR ARGS_COMPRESSION STREQUAL HUFFMAN) 529 | list(APPEND opts "-${x}zh") 530 | elseif(ARGS_COMPRESSION STREQUAL RLE OR ARGS_COMPRESSION STREQUAL RUN_LENGTH_ENCODING) 531 | list(APPEND opts "-${x}zr") 532 | elseif(ARGS_COMPRESSION) 533 | message(WARNING "Invalid grit compression type '${ARGS_COMPRESSION}'. Must be 'OFF', 'LZ77', 'HUFF', or 'RLE'.") 534 | endif() 535 | 536 | grit_copy_parsed_arguments(${prefix} ARGS "${options}" "${oneValueArgs}" "") 537 | set(${outArgs} ${options} ${oneValueArgs} PARENT_SCOPE) 538 | set(${outOptions} ${opts} PARENT_SCOPE) 539 | endfunction() 540 | 541 | function(grit_parse_arguments_graphics prefix outOptions) 542 | grit_parse_arguments_common(ARGS g opts commonArgs ${ARGN}) 543 | set(ARGN ${ARGS_UNPARSED_ARGUMENTS}) 544 | 545 | set(oneValueArgs 546 | BIT_DEPTH 547 | TRANSPARENT_COLOR 548 | ) 549 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN}) 550 | 551 | if(ARGS_BIT_DEPTH EQUAL 1 OR ARGS_BIT_DEPTH EQUAL 2 OR ARGS_BIT_DEPTH EQUAL 4 OR ARGS_BIT_DEPTH EQUAL 8 OR ARGS_BIT_DEPTH EQUAL 16) 552 | list(APPEND opts "-gB${ARGS_BIT_DEPTH}") 553 | elseif(ARGS_BIT_DEPTH) 554 | message(FATAL_ERROR "Unknown bit depth '${ARGS_BIT_DEPTH}'") 555 | endif() 556 | 557 | if(ARGS_TRANSPARENT_COLOR) 558 | list(APPEND opts "-gT${ARGS_TRANSPARENT_COLOR}") 559 | endif() 560 | 561 | grit_copy_arguments(${prefix} ARGS "${commonArgs}") 562 | grit_copy_parsed_arguments(${prefix} ARGS "" "${oneValueArgs}" "") 563 | 564 | set(${outOptions} ${opts} PARENT_SCOPE) 565 | endfunction() 566 | 567 | function(grit_parse_arguments_palette prefix outOptions) 568 | grit_parse_arguments_common(ARGS p opts commonArgs ${ARGN}) 569 | set(ARGN ${ARGS_UNPARSED_ARGUMENTS}) 570 | 571 | set(oneValueArgs 572 | START 573 | END 574 | TRANSPARENT_INDEX 575 | ) 576 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN}) 577 | 578 | if(ARGS_START) 579 | list(APPEND opts "-ps${ARGS_START}") 580 | endif() 581 | if(ARGS_END) 582 | list(APPEND opts "-pe${ARGS_END}") 583 | endif() 584 | 585 | if(ARGS_TRANSPARENT_INDEX MATCHES "[0-9]+") 586 | list(APPEND opts "-pT${ARGS_TRANSPARENT_INDEX}") 587 | elseif(ARGS_TRANSPARENT_INDEX) 588 | message(FATAL_ERROR "Transparent index '${ARGS_TRANSPARENT_INDEX}' is not a valid number") 589 | endif() 590 | 591 | grit_copy_arguments(${prefix} ARGS "${commonArgs}") 592 | grit_copy_parsed_arguments(${prefix} ARGS "" "${oneValueArgs}" "") 593 | 594 | set(${outOptions} ${opts} PARENT_SCOPE) 595 | endfunction() 596 | 597 | function(grit_parse_arguments_map prefix outOptions) 598 | grit_parse_arguments_common(ARGS m opts commonArgs ${ARGN}) 599 | set(ARGN ${ARGS_UNPARSED_ARGUMENTS}) 600 | 601 | set(oneValueArgs 602 | LAYOUT 603 | ENTRY_OFFSET 604 | ) 605 | set(multiValueArgs 606 | OPTIMIZE 607 | ) 608 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 609 | 610 | if(ARGS_LAYOUT STREQUAL FLAT) 611 | list(APPEND opts "-mLf") 612 | elseif(ARGS_LAYOUT STREQUAL SBB) 613 | list(APPEND opts "-mLs") 614 | elseif(ARGS_LAYOUT STREQUAL AFFINE) 615 | list(APPEND opts "-mLa") 616 | elseif(ARGS_LAYOUT) 617 | message(FATAL_ERROR "Unknown map layout '${ARGS_LAYOUT}'") 618 | endif() 619 | 620 | if(ARGS_ENTRY_OFFSET MATCHES "[0-9]+") 621 | list(APPEND opts "-ma${ARGS_ENTRY_OFFSET}") 622 | elseif(ARGS_TRANSPARENT_INDEX) 623 | message(FATAL_ERROR "Entry offset '${ARGS_ENTRY_OFFSET}' is not a valid number") 624 | endif() 625 | 626 | if(ARGS_OPTIMIZE STREQUAL NONE) 627 | list(APPEND opts "-mR!") 628 | elseif(ARGS_OPTIMIZE STREQUAL ALL) 629 | list(APPEND opts "-mRtpf") 630 | elseif(ARGS_OPTIMIZE) 631 | foreach(arg ${ARGS_OPTIMIZE}) 632 | if(arg STREQUAL TILES) 633 | string(APPEND optimize "t") 634 | elseif(arg STREQUAL PALETTES) 635 | string(APPEND optimize "p") 636 | elseif(arg STREQUAL FLIPPED) 637 | string(APPEND optimize "f") 638 | elseif(arg STREQUAL NONE) 639 | string(APPEND optimize "!") 640 | elseif(arg) 641 | message(FATAL_ERROR "Unknown map optimize level '${arg}'. Must be `TILES`, `PALETTES`, or `FLIPPED`.") 642 | endif() 643 | endforeach() 644 | list(APPEND opts "-mR${optimize}") 645 | endif() 646 | 647 | grit_copy_arguments(${prefix} ARGS "${commonArgs}") 648 | grit_copy_parsed_arguments(${prefix} ARGS "" "${oneValueArgs}" "${multiValueArgs}") 649 | 650 | set(${outOptions} ${opts} PARENT_SCOPE) 651 | endfunction() 652 | -------------------------------------------------------------------------------- /cmake/Modules/Findlibgba.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(ExternalProject) 9 | 10 | find_library(libgba gba PATHS "$ENV{DEVKITPRO}/libgba" "${CMAKE_SYSTEM_LIBRARY_PATH}/libgba" "${LIBGBA_DIR}" PATH_SUFFIXES lib) 11 | 12 | if(NOT libgba) 13 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/libgba") 14 | 15 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 16 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 17 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 18 | cmake_minimum_required(VERSION 3.18) 19 | project(libgba ASM C) 20 | 21 | file(GLOB sources "src/*.c" "src/*.s" "src/BoyScout/*.c" "src/disc_io/*.c" "src/disc_io/*.s") 22 | get_filename_component(console "${CMAKE_CURRENT_SOURCE_DIR}/src/console.c" ABSOLUTE) 23 | list(REMOVE_ITEM sources "${console}") 24 | 25 | add_library(gba STATIC ${sources}) 26 | target_include_directories(gba SYSTEM PUBLIC include) 27 | 28 | target_compile_options(gba PRIVATE 29 | $<$:-x assembler-with-cpp> 30 | $<$:-mthumb -O2 31 | -fno-strict-aliasing 32 | -fomit-frame-pointer 33 | -ffunction-sections 34 | -fdata-sections 35 | -Wall 36 | -Wextra 37 | -Wno-unused-parameter 38 | -Wno-sign-compare 39 | -Wno-old-style-declaration 40 | -Wno-discarded-qualifiers 41 | -Wno-multichar 42 | > 43 | ) 44 | 45 | install(TARGETS gba 46 | LIBRARY DESTINATION lib 47 | ) 48 | install(DIRECTORY include/ 49 | DESTINATION include 50 | ) 51 | ]=]) 52 | 53 | ExternalProject_Add(libgba_proj 54 | PREFIX "${SOURCE_DIR}" 55 | TMP_DIR "${SOURCE_DIR}/temp" 56 | STAMP_DIR "${SOURCE_DIR}/stamp" 57 | # Download 58 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 59 | GIT_REPOSITORY "https://github.com/devkitPro/libgba.git" 60 | GIT_TAG "master" 61 | # Update 62 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy 63 | "${SOURCE_DIR}/temp/CMakeLists.txt" 64 | "${SOURCE_DIR}/source/CMakeLists.txt" 65 | # Configure 66 | SOURCE_DIR "${SOURCE_DIR}/source" 67 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 68 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 69 | # Build 70 | BINARY_DIR "${SOURCE_DIR}/build" 71 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 72 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libgba.a" 73 | # Install 74 | INSTALL_DIR "${SOURCE_DIR}" 75 | ) 76 | 77 | add_library(libgba STATIC IMPORTED) 78 | add_dependencies(libgba libgba_proj) 79 | set_property(TARGET libgba PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libgba.a") 80 | target_include_directories(libgba INTERFACE "${SOURCE_DIR}/include") 81 | else() 82 | add_library(libgba STATIC IMPORTED) 83 | set_property(TARGET libgba PROPERTY IMPORTED_LOCATION "${libgba}") 84 | 85 | get_filename_component(INCLUDE_PATH "${libgba}" DIRECTORY) 86 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 87 | target_include_directories(libgba INTERFACE "${INCLUDE_PATH}/include") 88 | endif() 89 | 90 | unset(libgba CACHE) 91 | -------------------------------------------------------------------------------- /cmake/Modules/Findlibmultiboot.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | add_subdirectory("${CMAKE_SYSTEM_LIBRARY_PATH}/multiboot" "${CMAKE_BINARY_DIR}/lib/multiboot" EXCLUDE_FROM_ALL) 9 | -------------------------------------------------------------------------------- /cmake/Modules/Findlibrom.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | add_subdirectory("${CMAKE_SYSTEM_LIBRARY_PATH}/rom" "${CMAKE_BINARY_DIR}/lib/rom" EXCLUDE_FROM_ALL) 9 | -------------------------------------------------------------------------------- /cmake/Modules/Findlibseven.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(ExternalProject) 9 | 10 | find_library(libseven seven PATHS "$ENV{DEVKITPRO}/libseven" "${CMAKE_SYSTEM_LIBRARY_PATH}/libseven" "${LIBSEVEN_DIR}" PATH_SUFFIXES lib) 11 | 12 | if(NOT libseven) 13 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/libseven") 14 | 15 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 16 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 17 | ExternalProject_Add(libseven_proj 18 | PREFIX "${SOURCE_DIR}" 19 | TMP_DIR "${SOURCE_DIR}/temp" 20 | STAMP_DIR "${SOURCE_DIR}/stamp" 21 | # Download 22 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 23 | GIT_REPOSITORY "https://github.com/LunarLambda/sdk-seven.git" 24 | GIT_TAG "v0.27.0" 25 | # Configure 26 | SOURCE_DIR "${SOURCE_DIR}/source" 27 | SOURCE_SUBDIR "libseven" 28 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 29 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 30 | -DCMAKE_BUILD_TYPE:STRING=Release 31 | # Build 32 | BINARY_DIR "${SOURCE_DIR}/build" 33 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 34 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libseven.a" 35 | # Install 36 | INSTALL_DIR "${SOURCE_DIR}" 37 | ) 38 | 39 | add_library(libseven STATIC IMPORTED) 40 | add_dependencies(libseven libseven_proj) 41 | set_property(TARGET libseven PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libseven.a") 42 | target_include_directories(libseven INTERFACE "${SOURCE_DIR}/include") 43 | else() 44 | add_library(libseven STATIC IMPORTED) 45 | set_property(TARGET libseven PROPERTY IMPORTED_LOCATION "${libseven}") 46 | 47 | get_filename_component(INCLUDE_PATH "${libseven}" DIRECTORY) 48 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 49 | target_include_directories(libseven INTERFACE "${INCLUDE_PATH}/include") 50 | endif() 51 | 52 | unset(libseven CACHE) 53 | -------------------------------------------------------------------------------- /cmake/Modules/Findmaxmod.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Provides the CMake function `add_maxmod_soundbank` for adding a maxmod soundbank target 4 | # 5 | # maxmod targets also provide a header file in a `soundbanks/` subdirectory, available by linking with the target 6 | # The `BIN_FILE` property can be used as a file dependency 7 | # 8 | # Example: 9 | # ```cmake 10 | # add_maxmod_soundbank(my_soundbank path/to/my/music.xm path/to/other/sound.wav) 11 | # target_link_libraries(my_executable PRIVATE my_soundbank) 12 | # get_target_property(soundbank_bin_path my_soundbank BIN_FILE) 13 | # ``` 14 | # ```c 15 | # #include 16 | # #include 17 | # ``` 18 | # 19 | # Copyright (C) 2021-2023 gba-toolchain contributors 20 | # For conditions of distribution and use, see copyright notice in LICENSE.md 21 | # 22 | #=============================================================================== 23 | 24 | include(ExternalProject) 25 | 26 | find_library(libmm mm PATHS "$ENV{DEVKITPRO}/libgba" "${CMAKE_SYSTEM_LIBRARY_PATH}/maxmod" "${MAXMOD_DIR}" PATH_SUFFIXES lib) 27 | 28 | if(NOT libmm) 29 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/maxmod") 30 | 31 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 32 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 33 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 34 | cmake_minimum_required(VERSION 3.18) 35 | project(maxmod ASM) 36 | 37 | add_library(maxmod STATIC 38 | source/mm_effect.s 39 | source/mm_main.s 40 | source/mm_mas.s 41 | source/mm_mas_arm.s 42 | source_gba/mm_init_default.s 43 | source_gba/mm_main_gba.s 44 | source_gba/mm_mixer_gba.s 45 | ) 46 | set_target_properties(maxmod PROPERTIES OUTPUT_NAME "mm") 47 | 48 | target_include_directories(maxmod SYSTEM PUBLIC include/) 49 | target_include_directories(maxmod PRIVATE asm_include/) 50 | target_compile_definitions(maxmod PRIVATE SYS_GBA USE_IWRAM) 51 | target_compile_options(maxmod PRIVATE -x assembler-with-cpp) 52 | 53 | install(TARGETS maxmod 54 | LIBRARY DESTINATION lib 55 | ) 56 | install(DIRECTORY include/ 57 | DESTINATION include 58 | ) 59 | ]=]) 60 | 61 | ExternalProject_Add(maxmod_proj 62 | PREFIX "${SOURCE_DIR}" 63 | TMP_DIR "${SOURCE_DIR}/temp" 64 | STAMP_DIR "${SOURCE_DIR}/stamp" 65 | # Download 66 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 67 | GIT_REPOSITORY "https://github.com/devkitPro/maxmod.git" 68 | GIT_TAG "master" 69 | # Update 70 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy 71 | "${SOURCE_DIR}/temp/CMakeLists.txt" 72 | "${SOURCE_DIR}/source/CMakeLists.txt" 73 | # Configure 74 | SOURCE_DIR "${SOURCE_DIR}/source" 75 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 76 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 77 | # Build 78 | BINARY_DIR "${SOURCE_DIR}/build" 79 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 80 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libmm.a" 81 | # Install 82 | INSTALL_DIR "${SOURCE_DIR}" 83 | ) 84 | 85 | add_library(maxmod STATIC IMPORTED) 86 | add_dependencies(maxmod maxmod_proj) 87 | set_property(TARGET maxmod PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libmm.a") 88 | target_include_directories(maxmod INTERFACE "${SOURCE_DIR}/include") 89 | else() 90 | add_library(maxmod STATIC IMPORTED) 91 | set_property(TARGET maxmod PROPERTY IMPORTED_LOCATION "${libmm}") 92 | 93 | get_filename_component(INCLUDE_PATH "${libmm}" DIRECTORY) 94 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 95 | target_include_directories(maxmod INTERFACE "${INCLUDE_PATH}/include") 96 | endif() 97 | 98 | unset(libmm CACHE) 99 | 100 | find_program(CMAKE_MMUTIL_PROGRAM mmutil mmutil.exe PATHS "$ENV{DEVKITPRO}/tools" "${CMAKE_SYSTEM_LIBRARY_PATH}/maxmod" "${MMUTIL_DIR}" PATH_SUFFIXES bin) 101 | 102 | if(NOT CMAKE_MMUTIL_PROGRAM) 103 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/maxmod") 104 | 105 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp/mmutil") 106 | file(WRITE "${SOURCE_DIR}/temp/mmutil/CMakeLists.txt" [=[ 107 | cmake_minimum_required(VERSION 3.18) 108 | 109 | project(mmutil C) 110 | 111 | add_executable(mmutil 112 | source/adpcm.c 113 | source/files.c source/gba.c 114 | source/it.c source/kiwi.c source/main.c source/mas.c 115 | source/mod.c source/msl.c source/nds.c 116 | source/s3m.c source/samplefix.c 117 | source/simple.c source/upload.c 118 | source/wav.c source/xm.c 119 | ) 120 | 121 | target_include_directories(mmutil PRIVATE source) 122 | target_compile_definitions(mmutil PRIVATE PACKAGE_VERSION="1.9.1") 123 | 124 | if(NOT MSVC) 125 | target_link_libraries(mmutil PRIVATE m) 126 | endif() 127 | 128 | install(TARGETS mmutil DESTINATION bin) 129 | ]=]) 130 | 131 | FetchContent_Declare(mmutil_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 132 | PREFIX "${SOURCE_DIR}" 133 | TMP_DIR "${SOURCE_DIR}/temp/mmutil" 134 | STAMP_DIR "${SOURCE_DIR}/stamp/mmutil" 135 | SOURCE_DIR "${SOURCE_DIR}/source/mmutil" 136 | # Download 137 | DOWNLOAD_DIR "${SOURCE_DIR}/download/mmutil" 138 | GIT_REPOSITORY "https://github.com/devkitPro/mmutil.git" 139 | GIT_TAG "master" 140 | # Update 141 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy_if_different 142 | "${SOURCE_DIR}/temp/mmutil/CMakeLists.txt" 143 | "${SOURCE_DIR}/source/mmutil/CMakeLists.txt" 144 | ) 145 | 146 | FetchContent_Populate(mmutil_proj) 147 | 148 | # Configure 149 | execute_process( 150 | COMMAND "${CMAKE_COMMAND}" -S . -B "${SOURCE_DIR}/build/mmutil" 151 | WORKING_DIRECTORY "${SOURCE_DIR}/source/mmutil" 152 | RESULT_VARIABLE cmakeResult 153 | ) 154 | 155 | if(cmakeResult EQUAL "1") 156 | message(WARNING "Failed to configure mmutil") 157 | else() 158 | # Build 159 | execute_process( 160 | COMMAND "${CMAKE_COMMAND}" --build . --config Release 161 | WORKING_DIRECTORY "${SOURCE_DIR}/build/mmutil" 162 | RESULT_VARIABLE cmakeResult 163 | ) 164 | 165 | if(cmakeResult EQUAL "1") 166 | message(WARNING "Failed to build mmutil") 167 | else() 168 | # Install 169 | execute_process( 170 | COMMAND ${CMAKE_COMMAND} --install . --prefix "${SOURCE_DIR}" --config Release 171 | WORKING_DIRECTORY "${SOURCE_DIR}/build/mmutil" 172 | RESULT_VARIABLE cmakeResult 173 | ) 174 | 175 | if(cmakeResult EQUAL "1") 176 | message(WARNING "Failed to install mmutil") 177 | else() 178 | find_program(CMAKE_MMUTIL_PROGRAM mmutil PATHS "${SOURCE_DIR}/bin") 179 | endif() 180 | endif() 181 | endif() 182 | endif() 183 | 184 | if(NOT CMAKE_MMUTIL_PROGRAM) 185 | message(WARNING "mmutil not found: Please set `-DCMAKE_MMUTIL_PROGRAM:FILEPATH=`") 186 | endif() 187 | 188 | function(add_maxmod_soundbank target) 189 | set(ASSETS $) 190 | 191 | add_custom_command( 192 | OUTPUT ${target}.bin soundbank/${target}.h 193 | COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/soundbank" 194 | COMMAND "${CMAKE_MMUTIL_PROGRAM}" -o${CMAKE_CURRENT_BINARY_DIR}/${target}.bin -h${CMAKE_CURRENT_BINARY_DIR}/soundbank/${target}.h ${ASSETS} 195 | DEPENDS ${ASSETS} 196 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 197 | VERBATIM 198 | COMMAND_EXPAND_LISTS 199 | ) 200 | 201 | add_library(${target} INTERFACE) 202 | target_include_directories(${target} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) 203 | 204 | set_target_properties(${target} PROPERTIES 205 | ASSETS "${ARGN}" 206 | BIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/${target}.bin" 207 | ) 208 | endfunction() 209 | -------------------------------------------------------------------------------- /cmake/Modules/Findposprintf.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(ExternalProject) 9 | 10 | find_library(libposprintf posprintf PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/posprintf" "${POSPRINTF_DIR}" PATH_SUFFIXES lib) 11 | 12 | if(NOT libposprintf) 13 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/posprintf") 14 | 15 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 16 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 17 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 18 | cmake_minimum_required(VERSION 3.18) 19 | project(posprintf ASM) 20 | 21 | add_library(posprintf STATIC "posprintf/posprintf.S") 22 | 23 | install(TARGETS posprintf 24 | LIBRARY DESTINATION lib 25 | ) 26 | install(FILES "posprintf/posprintf.h" 27 | DESTINATION include 28 | ) 29 | ]=]) 30 | 31 | ExternalProject_Add(posprintf_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 32 | PREFIX "${SOURCE_DIR}" 33 | TMP_DIR "${SOURCE_DIR}/temp" 34 | STAMP_DIR "${SOURCE_DIR}/stamp" 35 | # Download 36 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 37 | URL "http://www.danposluns.com/gbadev/posprintf/posprintf.zip" 38 | URL_MD5 "f2cfce6b93764c59d84faa6c57ab1fbe" 39 | # Update 40 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy 41 | "${SOURCE_DIR}/temp/CMakeLists.txt" 42 | "${SOURCE_DIR}/source/CMakeLists.txt" 43 | # Configure 44 | SOURCE_DIR "${SOURCE_DIR}/source" 45 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 46 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 47 | # Build 48 | BINARY_DIR "${SOURCE_DIR}/build" 49 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 50 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libposprintf.a" 51 | # Install 52 | INSTALL_DIR "${SOURCE_DIR}" 53 | ) 54 | 55 | add_library(posprintf STATIC IMPORTED) 56 | add_dependencies(posprintf posprintf_proj) 57 | set_property(TARGET posprintf PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libposprintf.a") 58 | target_include_directories(posprintf INTERFACE "${SOURCE_DIR}/include") 59 | else() 60 | add_library(posprintf STATIC IMPORTED) 61 | set_property(TARGET posprintf PROPERTY IMPORTED_LOCATION "${libposprintf}") 62 | 63 | get_filename_component(INCLUDE_PATH "${libposprintf}" DIRECTORY) 64 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 65 | target_include_directories(posprintf INTERFACE "${INCLUDE_PATH}/include") 66 | endif() 67 | 68 | unset(libposprintf CACHE) 69 | -------------------------------------------------------------------------------- /cmake/Modules/Findsuperfamiconv.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Provides the CMake function `add_superfamiconv_graphics` for adding a superfamiconv assets target 4 | # 5 | # The `OUTPUT_FILES` property can be used as file dependencies 6 | # 7 | # Example: 8 | # ```cmake 9 | # # Generate palettes & tiles for sprites 10 | # add_superfamiconv_graphics(sprites PALETTE TILES SPRITE_MODE 11 | # path/to/my/sprite.png 12 | # path/to/another/sprite.png 13 | # ) 14 | # get_target_property(sprite_files sprites OUTPUT_FILES) 15 | # 16 | # # Generate palettes, tiles & maps for backgrounds 17 | # add_superfamiconv_graphics(backgrounds PALETTE TILES MAP 18 | # path/to/my/background.png 19 | # path/to/another/background.png 20 | # ) 21 | # get_target_property(background_files backgrounds OUTPUT_FILES) 22 | # 23 | # # Or individually access the palettes, tiles, maps 24 | # get_target_property(background_palettes backgrounds PALETTE_FILES) 25 | # get_target_property(background_tiles backgrounds TILES_FILES) 26 | # get_target_property(background_maps backgrounds MAP_FILES) 27 | # ``` 28 | # 29 | # Copyright (C) 2021-2023 gba-toolchain contributors 30 | # For conditions of distribution and use, see copyright notice in LICENSE.md 31 | # 32 | #=============================================================================== 33 | 34 | include(FetchContent) 35 | 36 | find_program(CMAKE_SUPERFAMICONV_PROGRAM superfamiconv superfamiconv.exe PATHS "${CMAKE_SYSTEM_LIBRARY_PATH}/superfamiconv" "${SUPERFAMICONV_DIR}" PATH_SUFFIXES bin) 37 | 38 | if(NOT CMAKE_SUPERFAMICONV_PROGRAM) 39 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/superfamiconv") 40 | 41 | FetchContent_Declare(superfamiconv_proj DOWNLOAD_EXTRACT_TIMESTAMP ON 42 | PREFIX "${SOURCE_DIR}" 43 | TMP_DIR "${SOURCE_DIR}/temp" 44 | STAMP_DIR "${SOURCE_DIR}/stamp" 45 | SOURCE_DIR "${SOURCE_DIR}/source" 46 | # Download 47 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 48 | GIT_REPOSITORY "https://github.com/Optiroc/SuperFamiconv.git" 49 | GIT_TAG "master" 50 | ) 51 | 52 | FetchContent_MakeAvailable(superfamiconv_proj) 53 | 54 | # Configure 55 | execute_process( 56 | COMMAND "${CMAKE_COMMAND}" -S . -B "${SOURCE_DIR}/build" 57 | WORKING_DIRECTORY "${SOURCE_DIR}/source" 58 | RESULT_VARIABLE cmakeResult 59 | ) 60 | 61 | if(cmakeResult EQUAL "1") 62 | message(WARNING "Failed to configure superfamiconv") 63 | else() 64 | # Build 65 | execute_process( 66 | COMMAND "${CMAKE_COMMAND}" --build . --config Release 67 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 68 | RESULT_VARIABLE cmakeResult 69 | ) 70 | 71 | if(cmakeResult EQUAL "1") 72 | message(WARNING "Failed to build superfamiconv") 73 | else() 74 | # Install 75 | execute_process( 76 | COMMAND ${CMAKE_COMMAND} --install . --prefix "${SOURCE_DIR}" --config Release 77 | WORKING_DIRECTORY "${SOURCE_DIR}/build" 78 | RESULT_VARIABLE cmakeResult 79 | ) 80 | 81 | if(cmakeResult EQUAL "1") 82 | message(WARNING "Failed to install superfamiconv") 83 | else() 84 | find_program(CMAKE_SUPERFAMICONV_PROGRAM superfamiconv PATHS "${SOURCE_DIR}/bin") 85 | endif() 86 | endif() 87 | endif() 88 | endif() 89 | 90 | if(NOT CMAKE_SUPERFAMICONV_PROGRAM) 91 | message(WARNING "superfamiconv not found: Please set `-DCMAKE_SUPERFAMICONV_PROGRAM:FILEPATH=`") 92 | endif() 93 | 94 | set(SUPERFAMICONV_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/../SuperFamiconv.cmake") 95 | 96 | function(add_superfamiconv_graphics target) 97 | set(options 98 | PALETTE 99 | TILES 100 | MAP 101 | SPRITE_MODE 102 | ) 103 | 104 | cmake_parse_arguments(ARGS "${options}" "" "" ${ARGN}) 105 | 106 | if(NOT ARGS_PALETTE AND NOT ARGS_TILES AND NOT ARGS_MAP) 107 | message(FATAL_ERROR "add_superfamiconv_graphics requires PALETTE, TILES, or MAP") 108 | endif() 109 | 110 | set(commands) 111 | set(outputs) 112 | 113 | if(ARGS_PALETTE) 114 | set(paletteOutputs) 115 | foreach(input ${ARGS_UNPARSED_ARGUMENTS}) 116 | get_filename_component(output "${input}" NAME_WE) 117 | list(APPEND paletteOutputs "${output}.palette") 118 | endforeach() 119 | list(APPEND outputs ${paletteOutputs}) 120 | 121 | add_custom_command( 122 | OUTPUT ${paletteOutputs} 123 | DEPENDS ${ARGS_UNPARSED_ARGUMENTS} 124 | COMMAND "${CMAKE_COMMAND}" -DPALETTE=ON 125 | "-DPROGRAM=${CMAKE_SUPERFAMICONV_PROGRAM}" 126 | "-DPREFIX=${CMAKE_CURRENT_BINARY_DIR}/" 127 | -DSUFFIX=.palette 128 | "-DINPUTS=${ARGS_UNPARSED_ARGUMENTS}" 129 | -P "${SUPERFAMICONV_SCRIPT}" 130 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 131 | VERBATIM 132 | ) 133 | endif() 134 | 135 | if(ARGS_TILES) 136 | set(tilesOutputs) 137 | foreach(input ${ARGS_UNPARSED_ARGUMENTS}) 138 | get_filename_component(output "${input}" NAME_WE) 139 | list(APPEND tilesOutputs "${output}.tiles") 140 | endforeach() 141 | list(APPEND outputs ${tilesOutputs}) 142 | 143 | add_custom_command( 144 | OUTPUT ${tilesOutputs} 145 | DEPENDS ${ARGS_UNPARSED_ARGUMENTS} ${paletteOutputs} 146 | COMMAND "${CMAKE_COMMAND}" -DTILES=ON 147 | "-DPROGRAM=${CMAKE_SUPERFAMICONV_PROGRAM}" 148 | "-DPARAMS=$,--no-discard,${ARGS_TILES}>" 149 | "-DPREFIX=${CMAKE_CURRENT_BINARY_DIR}/" 150 | -DSUFFIX=.tiles 151 | "-DPREFIX_PALETTE=${CMAKE_CURRENT_BINARY_DIR}/" 152 | -DSUFFIX_PALETTE=.palette 153 | "-DINPUTS=${ARGS_UNPARSED_ARGUMENTS}" 154 | -P "${SUPERFAMICONV_SCRIPT}" 155 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 156 | VERBATIM 157 | ) 158 | endif() 159 | 160 | if(ARGS_MAP) 161 | set(mapOutputs) 162 | foreach(input ${ARGS_UNPARSED_ARGUMENTS}) 163 | get_filename_component(output "${input}" NAME_WE) 164 | list(APPEND mapOutputs "${output}.map") 165 | endforeach() 166 | list(APPEND outputs ${mapOutputs}) 167 | 168 | add_custom_command( 169 | OUTPUT ${mapOutputs} 170 | DEPENDS ${ARGS_UNPARSED_ARGUMENTS} ${tilesOutputs} ${paletteOutputs} 171 | COMMAND "${CMAKE_COMMAND}" -DMAP=ON 172 | "-DPROGRAM=${CMAKE_SUPERFAMICONV_PROGRAM}" 173 | "-DPREFIX=${CMAKE_CURRENT_BINARY_DIR}/" 174 | -DSUFFIX=.map 175 | "-DPREFIX_PALETTE=${CMAKE_CURRENT_BINARY_DIR}/" 176 | -DSUFFIX_PALETTE=.palette 177 | "-DPREFIX_TILES=${CMAKE_CURRENT_BINARY_DIR}/" 178 | -DSUFFIX_TILES=.tiles 179 | "-DINPUTS=${ARGS_UNPARSED_ARGUMENTS}" 180 | -P "${SUPERFAMICONV_SCRIPT}" 181 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 182 | VERBATIM 183 | ) 184 | endif() 185 | 186 | add_custom_target(${target} DEPENDS ${outputs}) 187 | 188 | set(binaryOutput) 189 | foreach(output ${outputs}) 190 | list(APPEND binaryOutput "${CMAKE_CURRENT_BINARY_DIR}/${output}") 191 | endforeach() 192 | 193 | set_target_properties(${target} PROPERTIES 194 | OUTPUT_FILES "${binaryOutput}" 195 | PALETTE_FILES "${paletteOutputs}" 196 | TILES_FILES "${tilesOutputs}" 197 | MAP_FILES "${mapOutputs}" 198 | ) 199 | endfunction() 200 | -------------------------------------------------------------------------------- /cmake/Modules/Findtonclib.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(ExternalProject) 9 | 10 | find_library(libtonc tonc PATHS "$ENV{DEVKITPRO}/libtonc" "${CMAKE_SYSTEM_LIBRARY_PATH}/tonclib" "${TONCLIB_DIR}" PATH_SUFFIXES lib) 11 | 12 | if(NOT libtonc) 13 | set(SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/tonclib") 14 | 15 | file(MAKE_DIRECTORY "${SOURCE_DIR}/include") 16 | file(MAKE_DIRECTORY "${SOURCE_DIR}/temp") 17 | file(WRITE "${SOURCE_DIR}/temp/CMakeLists.txt" [=[ 18 | cmake_minimum_required(VERSION 3.18) 19 | project(tonclib ASM C) 20 | 21 | file(GLOB sources "asm/*.s" "src/*.c" "src/*.s" "src/font/*.s" "src/tte/*.c" "src/tte/*.s" "src/pre1.3/*.c" "src/pre1.3/*.s") 22 | get_filename_component(iohook "${CMAKE_CURRENT_SOURCE_DIR}/src/tte/tte_iohook.c" ABSOLUTE) 23 | list(REMOVE_ITEM sources "${iohook}") 24 | 25 | add_library(tonc STATIC ${sources}) 26 | target_include_directories(tonc SYSTEM PUBLIC include) 27 | 28 | target_compile_options(tonc PRIVATE 29 | $<$:-x assembler-with-cpp> 30 | $<$:-mthumb -O2 31 | -fno-strict-aliasing 32 | -fomit-frame-pointer 33 | -ffunction-sections 34 | -fdata-sections 35 | -Wall 36 | -Wextra 37 | -Wno-unused-parameter 38 | -Wno-char-subscripts 39 | -Wno-sign-compare 40 | -Wno-implicit-fallthrough 41 | -Wno-type-limits 42 | > 43 | ) 44 | 45 | install(TARGETS tonc 46 | LIBRARY DESTINATION lib 47 | ) 48 | install(DIRECTORY include/ 49 | DESTINATION include 50 | ) 51 | ]=]) 52 | 53 | ExternalProject_Add(libtonc 54 | PREFIX "${SOURCE_DIR}" 55 | TMP_DIR "${SOURCE_DIR}/temp" 56 | STAMP_DIR "${SOURCE_DIR}/stamp" 57 | # Download 58 | DOWNLOAD_DIR "${SOURCE_DIR}/download" 59 | GIT_REPOSITORY "https://github.com/devkitPro/libtonc.git" 60 | GIT_TAG "master" 61 | # Update 62 | UPDATE_COMMAND "${CMAKE_COMMAND}" -E copy 63 | "${SOURCE_DIR}/temp/CMakeLists.txt" 64 | "${SOURCE_DIR}/source/CMakeLists.txt" 65 | # Configure 66 | SOURCE_DIR "${SOURCE_DIR}/source" 67 | CMAKE_ARGS --toolchain "${CMAKE_TOOLCHAIN_FILE}" 68 | -DCMAKE_INSTALL_PREFIX:PATH='${SOURCE_DIR}' 69 | # Build 70 | BINARY_DIR "${SOURCE_DIR}/build" 71 | BUILD_COMMAND "${CMAKE_COMMAND}" --build . 72 | BUILD_BYPRODUCTS "${SOURCE_DIR}/build/libtonc.a" 73 | # Install 74 | INSTALL_DIR "${SOURCE_DIR}" 75 | ) 76 | 77 | add_library(tonclib STATIC IMPORTED) 78 | add_dependencies(tonclib libtonc) 79 | set_property(TARGET tonclib PROPERTY IMPORTED_LOCATION "${SOURCE_DIR}/build/libtonc.a") 80 | target_include_directories(tonclib INTERFACE "${SOURCE_DIR}/include") 81 | else() 82 | add_library(tonclib STATIC IMPORTED) 83 | set_property(TARGET tonclib PROPERTY IMPORTED_LOCATION "${libtonc}") 84 | 85 | get_filename_component(INCLUDE_PATH "${libtonc}" DIRECTORY) 86 | get_filename_component(INCLUDE_PATH "${INCLUDE_PATH}" DIRECTORY) 87 | target_include_directories(tonclib INTERFACE "${INCLUDE_PATH}/include") 88 | endif() 89 | 90 | unset(libtonc CACHE) 91 | -------------------------------------------------------------------------------- /cmake/Modules/Findxilefianlib.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(FetchContent) 9 | 10 | if(EXISTS "${CMAKE_SYSTEM_LIBRARY_PATH}/xilefianlib/CMakeLists.txt" OR EXISTS "${CMAKE_BINARY_DIR}/lib/xilefianlib/CMakeLists.txt") 11 | add_subdirectory("${CMAKE_SYSTEM_LIBRARY_PATH}/xilefianlib" "${CMAKE_BINARY_DIR}/lib/xilefianlib" EXCLUDE_FROM_ALL) 12 | else() 13 | FetchContent_Declare(xilefianlib DOWNLOAD_EXTRACT_TIMESTAMP ON 14 | SOURCE_DIR "${CMAKE_SYSTEM_LIBRARY_PATH}/xilefianlib" 15 | GIT_REPOSITORY "https://github.com/felixjones/xilefianlib.git" 16 | GIT_TAG "main" 17 | ) 18 | 19 | FetchContent_MakeAvailable(xilefianlib) 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/Modules/GbaFix.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(GBAFIX_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(gbafix infile) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${GBAFIX_SCRIPT}" -- "${infile}" "${ARGN}" 14 | ) 15 | endfunction() 16 | return() 17 | endif() 18 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 19 | 20 | # Collect arguments past -- into CMAKE_ARGN 21 | foreach(ii RANGE ${CMAKE_ARGC}) 22 | if(${ii} EQUAL ${CMAKE_ARGC}) 23 | break() 24 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 25 | set(start ${ii}) 26 | elseif(DEFINED start) 27 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 28 | endif() 29 | endforeach() 30 | unset(start) 31 | 32 | # Script begin 33 | 34 | cmake_policy(PUSH) 35 | cmake_policy(SET CMP0007 NEW) 36 | 37 | if(NOT CMAKE_ARGN) 38 | message(FATAL_ERROR "GbaFix requires input ROM.") 39 | endif() 40 | list(POP_FRONT CMAKE_ARGN input) # First arg is input 41 | 42 | cmake_policy(POP) 43 | 44 | # Parse arguments 45 | set(options 46 | DRY_RUN 47 | ) 48 | set(oneValueArgs 49 | TITLE 50 | ID 51 | MAKER 52 | VERSION 53 | ) 54 | cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "" ${CMAKE_ARGN}) 55 | 56 | # Validate args 57 | string(LENGTH "${ARGS_TITLE}" titleLength) 58 | if (${titleLength} GREATER 12) 59 | message(FATAL_ERROR "TITLE \"${ARGS_TITLE}\" must not be more than 12 characters") 60 | endif() 61 | 62 | string(LENGTH "${ARGS_ID}" idLength) 63 | if (${idLength} GREATER 4) 64 | message(FATAL_ERROR "ID \"${ARGS_ID}\" must not be more than 4 characters") 65 | endif() 66 | 67 | string(LENGTH "${ARGS_MAKER}" makerLength) 68 | if (${makerLength} GREATER 2) 69 | message(FATAL_ERROR "MAKER \"${ARGS_MAKER}\" must not be more than 2 characters") 70 | endif() 71 | 72 | if(ARGS_VERSION) 73 | math(EXPR HEX_VERSION "${ARGS_VERSION}" OUTPUT_FORMAT HEXADECIMAL) 74 | if(${HEX_VERSION} LESS 0 OR ${HEX_VERSION} GREATER 255) 75 | message(FATAL_ERROR "VERSION \"${ARGS_VERSION}\" must be between 0 and 255") 76 | endif() 77 | else() 78 | set(ARGS_VERSION 0) 79 | endif() 80 | 81 | # Useful after CMake math(EXPR ...) calls 82 | macro(normalize_hex hex nibbleCount) 83 | if(NOT "${${hex}}" MATCHES "0x") 84 | math(EXPR ${hex} "${${hex}}" OUTPUT_FORMAT HEXADECIMAL) 85 | endif() 86 | string(REGEX REPLACE "^0x" "" ${hex} "${${hex}}") 87 | string(REPEAT "0" ${nibbleCount} padding) 88 | set(${hex} "${padding}${${hex}}") 89 | string(LENGTH "${${hex}}" padding) 90 | math(EXPR padding "${padding} - ${nibbleCount}") 91 | string(SUBSTRING "${${hex}}" ${padding} -1 ${hex}) 92 | endmacro() 93 | 94 | # Pads a given string with ASCII '0' up until the given length 95 | macro(pad string length) 96 | string(LENGTH "${${string}}" stringLength) 97 | math(EXPR padLength "${length} - ${stringLength}") 98 | 99 | if(padLength GREATER 0) 100 | string(REPEAT "0" ${padLength} padding) 101 | set(${string} "${${string}}${padding}") 102 | endif() 103 | endmacro() 104 | 105 | # Convert to hex, apply padding, and normalize 106 | string(HEX "${ARGS_TITLE}" title) 107 | pad(title 24) 108 | string(HEX "${ARGS_ID}" id) 109 | pad(id 8) 110 | string(HEX "${ARGS_MAKER}" maker) 111 | pad(maker 4) 112 | normalize_hex(ARGS_VERSION 2) 113 | 114 | # Calculate header complement 115 | string(CONCAT header "${title}" "${id}" "${maker}" "96000000000000000000" "${ARGS_VERSION}") 116 | 117 | string(REGEX MATCHALL "([A-Fa-f0-9][A-Fa-f0-9])" headerBytes "${header}") 118 | set(complement 0) 119 | foreach(byte ${headerBytes}) 120 | math(EXPR complement "${complement} + 0x${byte}") 121 | endforeach() 122 | math(EXPR complement "-(0x19 + ${complement})" OUTPUT_FORMAT HEXADECIMAL) 123 | normalize_hex(complement 2) 124 | 125 | # For dry-run, we just pass the validation and return 126 | if(ARGS_DRY_RUN) 127 | if(ARGS_TITLE) 128 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Title = \"${ARGS_TITLE}\"") 129 | endif() 130 | if(ARGS_ID) 131 | unset(extra) 132 | 133 | # U code 134 | if(ARGS_ID MATCHES "^1") 135 | string(APPEND extra " [1] EverDrive EEPROM") 136 | elseif(ARGS_ID MATCHES "^2") 137 | string(APPEND extra " [2] EverDrive SRAM") 138 | elseif(ARGS_ID MATCHES "^3") 139 | string(APPEND extra " [3] EverDrive FLASH-64") 140 | elseif(ARGS_ID MATCHES "^4") 141 | string(APPEND extra " [4] EverDrive FLASH-128") 142 | endif() 143 | 144 | # D code 145 | if(ARGS_ID MATCHES "J$") 146 | string(APPEND extra " [J] Japan") 147 | elseif(ARGS_ID MATCHES "P$") 148 | string(APPEND extra " [P] Europe/Elsewhere") 149 | elseif(ARGS_ID MATCHES "F$") 150 | string(APPEND extra " [F] French") 151 | elseif(ARGS_ID MATCHES "S$") 152 | string(APPEND extra " [S] Spanish") 153 | elseif(ARGS_ID MATCHES "E$") 154 | string(APPEND extra " [E] USA/English") 155 | elseif(ARGS_ID MATCHES "D$") 156 | string(APPEND extra " [D] German") 157 | elseif(ARGS_ID MATCHES "I$") 158 | string(APPEND extra " [I] Italian") 159 | endif() 160 | 161 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "ID = \"${ARGS_ID}\"${extra}") 162 | endif() 163 | if(ARGS_MAKER) 164 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Maker = \"${ARGS_MAKER}\"") 165 | endif() 166 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Version = 0x${ARGS_VERSION}") 167 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Complement = 0x${complement}") 168 | return() 169 | endif() 170 | 171 | # Parse output argument 172 | cmake_policy(PUSH) 173 | cmake_policy(SET CMP0007 NEW) 174 | 175 | if(NOT ARGS_UNPARSED_ARGUMENTS) 176 | message(FATAL_ERROR "GbaFix requires output ROM.") 177 | endif() 178 | list(POP_FRONT ARGS_UNPARSED_ARGUMENTS output) # First un-parsed arg is output 179 | 180 | cmake_policy(POP) 181 | 182 | # Write fixed binary 183 | include("${CMAKE_CURRENT_LIST_DIR}/FileSplit.cmake") 184 | include("${CMAKE_CURRENT_LIST_DIR}/Hexdecode.cmake") 185 | include("${CMAKE_CURRENT_LIST_DIR}/Mktemp.cmake") 186 | 187 | # Split ROM into 3 parts 188 | mktemp(part1) 189 | mktemp(part2) 190 | mktemp(part3) 191 | 192 | file_split("${input}" 193 | OUTPUT "${part1}" LENGTH 160 # Entrypoint + Logo 194 | OUTPUT "${part2}" LENGTH 32 # Header 195 | OUTPUT "${part3}" # Remaining ROM 196 | ) 197 | 198 | # Override part2 with fixed header 199 | hexdecode("${part2}" "${header}" "${complement}" 0000) 200 | 201 | # Concat 202 | execute_process( 203 | COMMAND "${CMAKE_COMMAND}" -E cat "${part1}" "${part2}" "${part3}" 204 | OUTPUT_FILE "${output}" 205 | ) 206 | 207 | # Cleanup temporaries 208 | file(REMOVE "${part3}") 209 | file(REMOVE "${part2}") 210 | file(REMOVE "${part1}") 211 | -------------------------------------------------------------------------------- /cmake/Modules/Hexdecode.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(HEXDECODE_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(hexdecode outfile) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${HEXDECODE_SCRIPT}" -- "${outfile}" "${ARGN}" 14 | ) 15 | endfunction() 16 | return() 17 | endif() 18 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 19 | 20 | # Collect arguments past -- into CMAKE_ARGN 21 | foreach(ii RANGE ${CMAKE_ARGC}) 22 | if(${ii} EQUAL ${CMAKE_ARGC}) 23 | break() 24 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 25 | set(start ${ii}) 26 | elseif(DEFINED start) 27 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 28 | endif() 29 | endforeach() 30 | unset(start) 31 | 32 | # Script begin 33 | 34 | cmake_policy(PUSH) 35 | cmake_policy(SET CMP0007 NEW) 36 | 37 | list(LENGTH CMAKE_ARGN argc) 38 | if(argc LESS 2) 39 | message(FATAL_ERROR "hexdecode requires at least 2 arguments.") 40 | endif() 41 | 42 | list(POP_FRONT CMAKE_ARGN outfile) # First arg is output 43 | 44 | cmake_policy(POP) 45 | 46 | # Join all hex lists 47 | string(JOIN "" hexes ${CMAKE_ARGN}) 48 | 49 | # Decode hexes into outfile 50 | 51 | # Try if xxd is available 52 | find_program(XXD_EXECUTABLE NAMES xxd) 53 | if(XXD_EXECUTABLE) 54 | execute_process( 55 | COMMAND "${CMAKE_COMMAND}" -E echo_append "${hexes}" 56 | COMMAND "${XXD_EXECUTABLE}" --revert --ps 57 | OUTPUT_FILE "${outfile}" 58 | ) 59 | return() 60 | endif() 61 | 62 | # Try if powershell is available 63 | find_program(POWERSHELL_EXECUTABLE NAMES powershell pwsh) 64 | if(POWERSHELL_EXECUTABLE) 65 | execute_process( 66 | COMMAND "${POWERSHELL_EXECUTABLE}" -Command " 67 | $hexString = '${hexes}'; 68 | $byteArray = for ($i = 0; $i -lt $hexString.length; $i+=2) { 69 | [Convert]::ToByte($hexString.Substring($i, 2), 16) 70 | }; 71 | [IO.File]::WriteAllBytes('${outfile}', $byteArray) 72 | " 73 | ) 74 | return() 75 | endif() 76 | 77 | # Try if IHex and objcopy are available (SLOW!) 78 | include("${CMAKE_CURRENT_LIST_DIR}/IHex.cmake" OPTIONAL RESULT_VARIABLE IHEX_INCLUDED) 79 | include("${CMAKE_CURRENT_LIST_DIR}/Mktemp.cmake" OPTIONAL RESULT_VARIABLE MKTEMP_INCLUDED) 80 | find_program(OBJCOPY_EXECUTABLE NAMES objcopy) 81 | if(IHEX_INCLUDED AND MKTEMP_INCLUDED AND OBJCOPY_EXECUTABLE) 82 | ihex(outputHex RECORD_LENGTH 0xff ${hexes}) 83 | mktemp(tmpfile) 84 | 85 | file(WRITE "${tmpfile}" "${outputHex}") 86 | execute_process(COMMAND "${OBJCOPY_EXECUTABLE}" -I ihex "${tmpfile}" -O binary "${outfile}") 87 | file(REMOVE "${tmpfile}") 88 | 89 | return() 90 | endif() 91 | 92 | message(FATAL_ERROR "Failed to decode hex: Missing dependencies.") 93 | -------------------------------------------------------------------------------- /cmake/Modules/IHex.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(IHEX_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(ihex output) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${IHEX_SCRIPT}" -- "${ARGN}" 14 | OUTPUT_VARIABLE outputVariable OUTPUT_STRIP_TRAILING_WHITESPACE 15 | ) 16 | set("${output}" "${outputVariable}" PARENT_SCOPE) 17 | endfunction() 18 | return() 19 | endif() 20 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 21 | 22 | # Collect arguments past -- into CMAKE_ARGN 23 | foreach(ii RANGE ${CMAKE_ARGC}) 24 | if(${ii} EQUAL ${CMAKE_ARGC}) 25 | break() 26 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 27 | set(start ${ii}) 28 | elseif(DEFINED start) 29 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 30 | endif() 31 | endforeach() 32 | unset(start) 33 | 34 | # Script begin 35 | 36 | set(oneValueArgs RECORD_LENGTH) 37 | cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${CMAKE_ARGN}) 38 | 39 | if(NOT ARGS_UNPARSED_ARGUMENTS) 40 | message(FATAL_ERROR "ihex needs at least 1 input argument.") 41 | endif() 42 | list(JOIN ARGS_UNPARSED_ARGUMENTS "" input) 43 | 44 | string(REGEX MATCH "^[0-9A-Fa-f]+$" isHex ${input}) 45 | if(NOT isHex STREQUAL input) 46 | message(FATAL_ERROR "Input is not a valid hex string. ${input}") 47 | endif() 48 | 49 | if(NOT ARGS_RECORD_LENGTH) 50 | set(ARGS_RECORD_LENGTH 16) 51 | endif() 52 | math(EXPR nibbleLength "${ARGS_RECORD_LENGTH} * 2") 53 | 54 | # Useful after CMake math(EXPR ...) calls 55 | macro(normalize_hex hex nibbleCount) 56 | if(NOT "${${hex}}" MATCHES "0x") 57 | math(EXPR ${hex} "${${hex}}" OUTPUT_FORMAT HEXADECIMAL) 58 | endif() 59 | string(REGEX REPLACE "^0x" "" ${hex} "${${hex}}") 60 | string(REPEAT "0" ${nibbleCount} padding) 61 | set(${hex} "${padding}${${hex}}") 62 | string(LENGTH "${${hex}}" padding) 63 | math(EXPR padding "${padding} - ${nibbleCount}") 64 | string(SUBSTRING "${${hex}}" ${padding} -1 ${hex}) 65 | endmacro() 66 | 67 | # ihex checksum algorithm 68 | macro(checksum result hexNibbles) 69 | string(REGEX MATCHALL "([A-Fa-f0-9][A-Fa-f0-9])" hexBytes ${${hexNibbles}}) 70 | 71 | set(${result} 0) 72 | foreach(byte ${hexBytes}) 73 | math(EXPR ${result} "${${result}} + 0x${byte}") 74 | endforeach() 75 | math(EXPR ${result} "1 + ~${${result}}" OUTPUT_FORMAT HEXADECIMAL) 76 | normalize_hex(${result} 2) 77 | endmacro() 78 | 79 | string(LENGTH "${input}" length) 80 | 81 | set(addrMajor 0000) 82 | set(addrMinor 0000) 83 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo ":020000040000fa") # Start major address 0000 84 | 85 | set(idx 0) 86 | while(idx LESS ${length}) 87 | # Write a row of data 88 | string(SUBSTRING "${input}" ${idx} ${nibbleLength} dataString) 89 | string(LENGTH "${dataString}" dataLength) 90 | math(EXPR dataLength "${dataLength} / 2") 91 | normalize_hex(dataLength 2) 92 | 93 | set(dataString "${dataLength}${addrMinor}00${dataString}") 94 | checksum(crc dataString) 95 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo ":${dataString}${crc}") 96 | 97 | # Calculate next minor address 98 | math(EXPR addrMinor "0x${addrMinor} + ${ARGS_RECORD_LENGTH}" OUTPUT_FORMAT HEXADECIMAL) 99 | 100 | if("${addrMinor}" GREATER_EQUAL 0x10000) 101 | # Calculate next major address 102 | math(EXPR addrMajor "0x${addrMajor} + 1" OUTPUT_FORMAT HEXADECIMAL) 103 | math(EXPR addrMinor "${addrMinor} - 0x10000" OUTPUT_FORMAT HEXADECIMAL) 104 | 105 | normalize_hex(addrMajor 4) 106 | set(extendedAddress "02000004${addrMajor}") 107 | checksum(crc extendedAddress) 108 | 109 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo ":${extendedAddress}${crc}") 110 | endif() 111 | 112 | normalize_hex(addrMinor 4) 113 | 114 | math(EXPR idx "${idx} + ${nibbleLength}") 115 | endwhile() 116 | 117 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo ":00000001ff") # EOF marker 118 | -------------------------------------------------------------------------------- /cmake/Modules/Mktemp.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | # Create include() function 9 | if(NOT CMAKE_SCRIPT_MODE_FILE) 10 | set(MKTEMP_SCRIPT "${CMAKE_CURRENT_LIST_FILE}") 11 | function(mktemp output) 12 | execute_process( 13 | COMMAND "${CMAKE_COMMAND}" -P "${MKTEMP_SCRIPT}" -- "${ARGN}" 14 | OUTPUT_VARIABLE outputVariable OUTPUT_STRIP_TRAILING_WHITESPACE 15 | ) 16 | set("${output}" "${outputVariable}" PARENT_SCOPE) 17 | endfunction() 18 | return() 19 | endif() 20 | unset(CMAKE_SCRIPT_MODE_FILE) # Enable nested include() 21 | 22 | # Collect arguments past -- into CMAKE_ARGN 23 | foreach(ii RANGE ${CMAKE_ARGC}) 24 | if(${ii} EQUAL ${CMAKE_ARGC}) 25 | break() 26 | elseif("${CMAKE_ARGV${ii}}" STREQUAL --) 27 | set(start ${ii}) 28 | elseif(DEFINED start) 29 | list(APPEND CMAKE_ARGN "${CMAKE_ARGV${ii}}") 30 | endif() 31 | endforeach() 32 | unset(start) 33 | 34 | # Script begin 35 | set(options 36 | TMPDIR 37 | DIRECTORY 38 | DRY_RUN 39 | ) 40 | set(oneValueArgs 41 | SUFFIX 42 | PREFIX 43 | ) 44 | cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "" ${CMAKE_ARGN}) 45 | 46 | # Find template and templateLength 47 | if(NOT ARGS_UNPARSED_ARGUMENTS) 48 | set(template "tmp.") 49 | set(templateLength 10) 50 | else() 51 | string(REGEX MATCH "XXX+$" chars "${ARGS_UNPARSED_ARGUMENTS}") 52 | string(LENGTH "${chars}" templateLength) 53 | 54 | if(templateLength LESS 3) 55 | message(FATAL_ERROR "TEMPLATE must contain at least 3 consecutive `X's in last component.") 56 | endif() 57 | 58 | string(LENGTH "${ARGS_UNPARSED_ARGUMENTS}" sublen) 59 | math(EXPR sublen "${sublen} - ${templateLength}") 60 | string(SUBSTRING "${ARGS_UNPARSED_ARGUMENTS}" 0 ${sublen} template) 61 | endif() 62 | 63 | # Find temporary directory 64 | if(ARGS_TMPDIR) 65 | if(DEFINED ENV{tmp}) 66 | file(TO_CMAKE_PATH "$ENV{tmp}" ARGS_TMPDIR) 67 | string(APPEND ARGS_TMPDIR /) 68 | else() 69 | set(ARGS_TMPDIR /tmp/) 70 | endif() 71 | else() 72 | unset(ARGS_TMPDIR) 73 | endif() 74 | 75 | # Attempt to generate unique path 76 | string(RANDOM LENGTH ${templateLength} random) 77 | while(EXISTS "${ARGS_TMPDIR}${ARGS_PREFIX}${template}${random}${ARGS_SUFFIX}") 78 | string(RANDOM LENGTH ${templateLength} random) 79 | endwhile() 80 | set(result "${ARGS_TMPDIR}${ARGS_PREFIX}${template}${random}${ARGS_SUFFIX}") 81 | 82 | # When not dry running, actually create the directory/file 83 | if(NOT ARGS_DRY_RUN) 84 | if(ARGS_DIRECTORY) 85 | file(MAKE_DIRECTORY "${result}") 86 | else() 87 | file(TOUCH "${result}") 88 | endif() 89 | endif() 90 | 91 | execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "${result}") 92 | -------------------------------------------------------------------------------- /cmake/Platform/AdvancedGameBoy-Clang-C.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(Compiler/CMakeCommonCompilerMacros) 9 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake) 10 | cmake_determine_compile_features(C) 11 | 12 | set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") 13 | set(CMAKE_C_FLAGS_DEBUG_INIT "-O0 -g -D_DEBUG") 14 | set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-Og -g -DNDEBUG") 15 | set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") 16 | -------------------------------------------------------------------------------- /cmake/Platform/AdvancedGameBoy-Clang-CXX.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(Compiler/CMakeCommonCompilerMacros) 9 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake) 10 | cmake_determine_compile_features(CXX) 11 | 12 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") 13 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "-O0 -g -D_DEBUG") 14 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-Og -g -DNDEBUG") 15 | set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") 16 | -------------------------------------------------------------------------------- /cmake/Platform/AdvancedGameBoy-GNU-C.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(Compiler/CMakeCommonCompilerMacros) 9 | 10 | if(CMAKE_VERSION VERSION_LESS "3.30.0") 11 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake) 12 | cmake_determine_compile_features(C) 13 | else() 14 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerSupport.cmake) 15 | cmake_determine_compiler_support(C) 16 | endif() 17 | 18 | set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") 19 | set(CMAKE_C_FLAGS_DEBUG_INIT "-O0 -g -D_DEBUG") 20 | set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-Og -g -DNDEBUG") 21 | set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") 22 | -------------------------------------------------------------------------------- /cmake/Platform/AdvancedGameBoy-GNU-CXX.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | include(Compiler/CMakeCommonCompilerMacros) 9 | 10 | if(CMAKE_VERSION VERSION_LESS "3.30.0") 11 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake) 12 | cmake_determine_compile_features(CXX) 13 | else() 14 | include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerSupport.cmake) 15 | cmake_determine_compiler_support(CXX) 16 | endif() 17 | 18 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") 19 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "-O0 -g -D_DEBUG") 20 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-Og -g -DNDEBUG") 21 | set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") 22 | -------------------------------------------------------------------------------- /cmake/Platform/AdvancedGameBoy.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Provides the CMake function `install_rom` for installing a GBA .elf archive into a .gba ROM file 4 | # 5 | # The GBA header is configured with the `ROM_TITLE`, `ROM_ID`, `ROM_MAKER`, and `ROM_VERSION` target properties 6 | # The optional `CONCAT` parameter allows for concatenating binary data to the .gba file 7 | # When using `CONCAT`, the optional `ALIGN` parameter sets a byte alignment for the concatenated binary data 8 | # 9 | # Example: 10 | # ```cmake 11 | # set_target_properties(my_executable PROPERTIES 12 | # ROM_TITLE "My Title" 13 | # ROM_ID AXYE 14 | # ROM_MAKER ZW 15 | # ROM_VERSION 1 16 | # ) 17 | # install_rom(my_executable CONCAT ALIGN 0x100 18 | # binary_file.bin 19 | # another_binary_file.bin 20 | # $ 21 | # ) 22 | # ``` 23 | # 24 | # Provides the CMake function `add_asset_library` for archiving assets files to a `.s` assembly file 25 | # 26 | # asset library targets convert the input files into a `.s` assembly file, available by linking with the target 27 | # 28 | # Example: 29 | # ```cmake 30 | # add_asset_library(my_assets 31 | # path/to/my/file.bin 32 | # path/to/another/file.txt 33 | # $ 34 | # ) 35 | # target_link_libraries(my_executable PRIVATE my_assets) 36 | # ``` 37 | # 38 | # Copyright (C) 2021-2023 gba-toolchain contributors 39 | # For conditions of distribution and use, see copyright notice in LICENSE.md 40 | # 41 | #=============================================================================== 42 | 43 | foreach(suffix "" _ASM _C _CXX) 44 | set(CMAKE_EXECUTABLE_FORMAT${suffix} ELF CACHE INTERNAL "") 45 | set(CMAKE_EXECUTABLE_SUFFIX${suffix} .elf CACHE INTERNAL "") 46 | endforeach() 47 | 48 | # Setup default install prefix 49 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 50 | set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}" CACHE PATH "Installation prefix path for the project install step" FORCE) 51 | endif() 52 | 53 | include(GbaFix) 54 | include(Mktemp) 55 | include(Bincat) 56 | 57 | function(install_rom target) 58 | if(NOT TARGET ${target}) 59 | message(FATAL_ERROR "No target \"${target}\"") 60 | return() 61 | endif() 62 | 63 | cmake_parse_arguments(ARGS "" "DESTINATION" "CONCAT" ${ARGN}) 64 | if(NOT ARGS_DESTINATION) 65 | set(ARGS_DESTINATION ".") 66 | endif() 67 | 68 | # Add gbafix checking command 69 | add_custom_command(TARGET ${target} PRE_BUILD 70 | COMMAND "${CMAKE_COMMAND}" -P "${GBAFIX_SCRIPT}" -- $ DRY_RUN 71 | TITLE $ 72 | ID $ 73 | MAKER $ 74 | VERSION $ 75 | ) 76 | 77 | set(INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${ARGS_DESTINATION}") 78 | 79 | # Install the .elf 80 | install(TARGETS ${target} DESTINATION "${ARGS_DESTINATION}") 81 | 82 | # objcopy and gbafix 83 | install(CODE " 84 | execute_process( 85 | COMMAND \"${CMAKE_OBJCOPY}\" -O binary \"$\" \"$.bin\" 86 | COMMAND \"${CMAKE_COMMAND}\" -P \"${GBAFIX_SCRIPT}\" -- \"$.bin\" 87 | \"$.gba\" 88 | TITLE \"$\" 89 | ID \"$\" 90 | MAKER \"$\" 91 | VERSION \"$\" 92 | WORKING_DIRECTORY \"${INSTALL_DESTINATION}\" 93 | ) 94 | ") 95 | 96 | if(NOT ARGS_CONCAT) 97 | return() 98 | endif() 99 | 100 | cmake_parse_arguments(CONCAT_ARGS "" "ALIGN" "" ${ARGS_CONCAT}) 101 | 102 | if(NOT CONCAT_ARGS_ALIGN) 103 | set(CONCAT_ARGS_ALIGN 1) 104 | endif() 105 | 106 | # List files to be appended 107 | foreach(concat ${CONCAT_ARGS_UNPARSED_ARGUMENTS}) 108 | if(NOT TARGET ${concat}) 109 | get_filename_component(concat "${concat}" ABSOLUTE) 110 | list(APPEND appendFiles ${concat}) 111 | else() 112 | add_dependencies(${target} ${concat}) 113 | list(APPEND appendFiles $>) 114 | endif() 115 | endforeach() 116 | 117 | # Append files 118 | install(CODE " 119 | execute_process( 120 | COMMAND \"${CMAKE_COMMAND}\" -P \"${MKTEMP_SCRIPT}\" 121 | OUTPUT_VARIABLE tmpfile OUTPUT_STRIP_TRAILING_WHITESPACE 122 | WORKING_DIRECTORY \"${INSTALL_DESTINATION}\" 123 | ) 124 | 125 | execute_process( 126 | COMMAND \"${CMAKE_COMMAND}\" -P \"${BINCAT_SCRIPT}\" -- 127 | \"$.gba\" 128 | \"\${tmpfile}\" 129 | ${CONCAT_ARGS_ALIGN} 130 | ${appendFiles} 131 | WORKING_DIRECTORY \"${INSTALL_DESTINATION}\" 132 | ) 133 | 134 | file(REMOVE \"${INSTALL_DESTINATION}/$.gba\") 135 | file(RENAME \"${INSTALL_DESTINATION}/\${tmpfile}\" \"${INSTALL_DESTINATION}/$.gba\") 136 | ") 137 | endfunction() 138 | 139 | find_program(CMAKE_BIN2S_PROGRAM bin2s bin2s.exe PATHS "$ENV{DEVKITPRO}/tools" "${CMAKE_SYSTEM_LIBRARY_PATH}/gbfs" "${GBFS_DIR}" PATH_SUFFIXES bin) 140 | include(Bin2s) 141 | 142 | function(add_asset_library target) 143 | set(assetsEval $>) 144 | 145 | if(CMAKE_BIN2S_PROGRAM) 146 | set(bin2sCommand "${CMAKE_BIN2S_PROGRAM}") 147 | else() 148 | set(bin2sCommand "${CMAKE_COMMAND}" -P "${BIN2S_SCRIPT}" --) 149 | endif() 150 | 151 | add_custom_command( 152 | OUTPUT ${target}.s 153 | COMMAND ${bin2sCommand} "${assetsEval}" > "${CMAKE_CURRENT_BINARY_DIR}/${target}.s" 154 | DEPENDS ${assetsEval} 155 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 156 | COMMAND_EXPAND_LISTS 157 | ) 158 | 159 | add_library(${target} OBJECT ${target}.s) 160 | 161 | set_target_properties(${target} PROPERTIES 162 | ASSETS "${ARGN}" 163 | ) 164 | endfunction() 165 | -------------------------------------------------------------------------------- /cmake/SuperFamiconv.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # CMake script for running the `superfamiconv` tool on image files 4 | # 5 | # Copyright (C) 2021-2023 gba-toolchain contributors 6 | # For conditions of distribution and use, see copyright notice in LICENSE.md 7 | # 8 | #=============================================================================== 9 | 10 | if(PALETTE) 11 | foreach(INPUT ${INPUTS}) 12 | get_filename_component(OUTPUT "${INPUT}" NAME_WE) 13 | execute_process(COMMAND "${PROGRAM}" palette 14 | --in-image "${INPUT}" 15 | --out-data "${PREFIX}${OUTPUT}${SUFFIX}" 16 | --mode gba 17 | ${PARAMS} 18 | ) 19 | endforeach() 20 | endif() 21 | 22 | if(TILES) 23 | foreach(INPUT ${INPUTS}) 24 | get_filename_component(OUTPUT "${INPUT}" NAME_WE) 25 | set(INPUT_PALETTE "${PREFIX_PALETTE}${OUTPUT}${SUFFIX_PALETTE}") 26 | execute_process(COMMAND "${PROGRAM}" tiles 27 | --in-image "${INPUT}" 28 | --in-palette "${INPUT_PALETTE}" 29 | --out-data "${PREFIX}${OUTPUT}${SUFFIX}" 30 | --mode gba 31 | ${PARAMS} 32 | ) 33 | endforeach() 34 | endif() 35 | 36 | if(MAP) 37 | foreach(INPUT ${INPUTS}) 38 | get_filename_component(OUTPUT "${INPUT}" NAME_WE) 39 | set(INPUT_PALETTE "${PREFIX_PALETTE}${OUTPUT}${SUFFIX_PALETTE}") 40 | set(INPUT_TILES "${PREFIX_TILES}${OUTPUT}${SUFFIX_TILES}") 41 | execute_process(COMMAND "${PROGRAM}" map 42 | --in-image "${INPUT}" 43 | --in-palette "${INPUT_PALETTE}" 44 | --in-tiles "${INPUT_TILES}" 45 | --out-data "${PREFIX}${OUTPUT}${SUFFIX}" 46 | --mode gba 47 | ${PARAMS} 48 | ) 49 | endforeach() 50 | endif() 51 | -------------------------------------------------------------------------------- /cmake/gba.toolchain.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # CMake toolchain file 4 | # Use with `--toolchain=/path/to/gba.toolchain.cmake` 5 | # Arm compiler tools are required 6 | # Using this toolchain file will enable several CMake modules within `/Modules` 7 | # 8 | # Copyright (C) 2021-2023 gba-toolchain contributors 9 | # For conditions of distribution and use, see copyright notice in LICENSE.md 10 | # 11 | #=============================================================================== 12 | 13 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/Modules") 14 | 15 | set(CMAKE_SYSTEM_NAME AdvancedGameBoy CACHE INTERNAL "") 16 | set(CMAKE_SYSTEM_VERSION 1 CACHE INTERNAL "") 17 | set(CMAKE_SYSTEM_PROCESSOR armv4t CACHE INTERNAL "") 18 | 19 | if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") 20 | if(CMAKE_GENERATOR MATCHES "Visual Studio") 21 | message(FATAL_ERROR "Toolchain is not compatible with Visual Studio (Use -G \"Ninja\" or -G \"Unix Makefiles\")") 22 | endif() 23 | 24 | if(CMAKE_GENERATOR STREQUAL "NMake Makefiles") 25 | message(FATAL_ERROR "Toolchain is not compatible with NMake (Use -G \"Ninja\" or -G \"Unix Makefiles\")") 26 | endif() 27 | 28 | # Fixup devkitPro default environment paths for Windows 29 | # This is not guaranteed to produce a correct path for devkitPro 30 | string(REGEX REPLACE "^/opt/" "C:/" DEVKITPRO "$ENV{DEVKITPRO}") 31 | string(REGEX REPLACE "^/opt/" "C:/" DEVKITARM "$ENV{DEVKITARM}") 32 | set(ENV{DEVKITPRO} "${DEVKITPRO}") 33 | set(ENV{DEVKITARM} "${DEVKITARM}") 34 | unset(DEVKITPRO) 35 | unset(DEVKITARM) 36 | 37 | # Find default install path for Arm GNU Toolchain 38 | unset(programfiles) 39 | foreach(v "ProgramW6432" "ProgramFiles" "ProgramFiles(x86)") 40 | if(DEFINED "ENV{${v}}") 41 | file(TO_CMAKE_PATH "$ENV{${v}}" envProgramfiles) 42 | list(APPEND programfiles "$envProgramfiles}") 43 | unset(envProgramfiles) 44 | endif() 45 | endforeach() 46 | 47 | if(DEFINED "ENV{SystemDrive}") 48 | foreach(d "Program Files" "Program Files (x86)") 49 | if(EXISTS "$ENV{SystemDrive}/${d}") 50 | list(APPEND programfiles "$ENV{SystemDrive}/${d}") 51 | endif() 52 | endforeach() 53 | endif() 54 | 55 | if(programfiles) 56 | list(REMOVE_DUPLICATES programfiles) 57 | find_path(GNUARM "Arm GNU Toolchain arm-none-eabi" PATHS ${programfiles}) 58 | unset(programfiles) 59 | endif() 60 | 61 | if(GNUARM) 62 | file(GLOB GNUARM "${GNUARM}/Arm GNU Toolchain arm-none-eabi/*") 63 | endif() 64 | endif() 65 | 66 | if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") 67 | find_path(GNUARM "ArmGNUToolchain" PATHS "/Applications") 68 | 69 | if(GNUARM) 70 | file(GLOB GNUARM "${GNUARM}/ArmGNUToolchain/*/arm-none-eabi") 71 | endif() 72 | endif() 73 | 74 | # Fixup MSYS search paths 75 | if(CMAKE_HOST_SYSTEM_NAME STREQUAL "MSYS") 76 | # Disallow msys2 CMake 77 | if(CMAKE_COMMAND MATCHES "msys2") 78 | message(FATAL_ERROR "${CMAKE_COMMAND} is known to cause problems. Please use an alternative CMake executable.") 79 | endif() 80 | 81 | if(DEFINED "ENV{GNUARM}") 82 | execute_process(COMMAND cygpath -u "$ENV{GNUARM}" OUTPUT_VARIABLE GNUARM OUTPUT_STRIP_TRAILING_WHITESPACE) 83 | set(ENV{GNUARM} "${GNUARM}") 84 | unset(GNUARM) 85 | endif() 86 | 87 | if(DEFINED "ENV{DEVKITPRO}") 88 | execute_process(COMMAND cygpath -u "$ENV{DEVKITPRO}" OUTPUT_VARIABLE DEVKITPRO OUTPUT_STRIP_TRAILING_WHITESPACE) 89 | set(ENV{DEVKITPRO} "${DEVKITPRO}") 90 | unset(DEVKITPRO) 91 | endif() 92 | 93 | if(DEFINED "ENV{DEVKITARM}") 94 | execute_process(COMMAND cygpath -u "$ENV{DEVKITARM}" OUTPUT_VARIABLE DEVKITARM OUTPUT_STRIP_TRAILING_WHITESPACE) 95 | set(ENV{DEVKITARM} "${DEVKITARM}") 96 | unset(DEVKITARM) 97 | endif() 98 | endif() 99 | 100 | if(GNUARM) 101 | list(SORT GNUARM COMPARE NATURAL ORDER DESCENDING) 102 | list(POP_FRONT GNUARM GNUARM_LATEST) 103 | endif() 104 | unset(GNUARM CACHE) 105 | if(GNUARM_LATEST) 106 | set(ENV{GNUARM} "${GNUARM_LATEST}") 107 | unset(GNUARM_LATEST) 108 | endif() 109 | 110 | set(COMPILER_SEARCH_PATHS "$ENV{GNUARM}" "$ENV{DEVKITARM}" "$ENV{DEVKITPRO}/devkitARM") 111 | 112 | # Set library prefixes and suffixes 113 | if(NOT CMAKE_FIND_LIBRARY_PREFIXES OR NOT CMAKE_FIND_LIBRARY_SUFFIXES) 114 | set(CMAKE_FIND_LIBRARY_PREFIXES "lib" CACHE INTERNAL "") 115 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a" CACHE INTERNAL "") 116 | endif() 117 | 118 | # Set CMAKE_MAKE_PROGRAM for Unix Makefiles 119 | if(CMAKE_GENERATOR STREQUAL "Unix Makefiles" AND NOT CMAKE_MAKE_PROGRAM) 120 | find_program(CMAKE_MAKE_PROGRAM NAMES make mingw32-make gmake) 121 | 122 | # DEVKITPRO sometimes has make 123 | if(NOT CMAKE_MAKE_PROGRAM) 124 | find_program(CMAKE_MAKE_PROGRAM NAMES make PATHS "$ENV{DEVKITPRO}/msys2/usr" PATH_SUFFIXES bin REQUIRED) 125 | endif() 126 | endif() 127 | 128 | # TODO: Set up linker to allow executable test compile 129 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE INTERNAL "") 130 | 131 | function(find_arm_compiler lang binary) 132 | # Detects clang, clang++, gcc, g++ 133 | macro(detect_compiler_id) 134 | set(COMPILER_BASENAME "${CMAKE_${lang}_COMPILER}") 135 | 136 | if(COMPILER_BASENAME MATCHES "($|[^a-zA-Z])((clang)|(clang\\+\\+))") 137 | set(CMAKE_${lang}_COMPILER_ID Clang CACHE INTERNAL "") 138 | elseif(COMPILER_BASENAME MATCHES "($|[^a-zA-Z])((gcc)|(g\\+\\+))") 139 | set(CMAKE_${lang}_COMPILER_ID GNU CACHE INTERNAL "") 140 | else() 141 | message(FATAL_ERROR "Unknown compiler ${CMAKE_${lang}_COMPILER}") 142 | endif() 143 | 144 | execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -dumpversion OUTPUT_VARIABLE version OUTPUT_STRIP_TRAILING_WHITESPACE) 145 | set(CMAKE_${lang}_COMPILER_VERSION "${version}" CACHE INTERNAL "") 146 | set(CMAKE_${lang}_COMPILER_FORCED ON CACHE INTERNAL "") 147 | endmacro() 148 | 149 | if(CMAKE_${lang}_COMPILER) 150 | detect_compiler_id() 151 | 152 | # Make sure compiler is ARM capable 153 | if(CMAKE_${lang}_COMPILER_ID MATCHES "Clang") 154 | execute_process(COMMAND ${CMAKE_${lang}_COMPILER} -print-targets OUTPUT_VARIABLE TARGETS OUTPUT_STRIP_TRAILING_WHITESPACE) 155 | 156 | if(NOT TARGETS MATCHES "arm[ \t\r\n]*") 157 | unset(CMAKE_${lang}_COMPILER CACHE) 158 | endif() 159 | elseif(CMAKE_${lang}_COMPILER_ID MATCHES "GNU") 160 | execute_process(COMMAND ${CMAKE_${lang}_COMPILER} -dumpmachine OUTPUT_VARIABLE DUMP OUTPUT_STRIP_TRAILING_WHITESPACE) 161 | 162 | if(NOT DUMP MATCHES "arm\\-none\\-eabi") 163 | unset(CMAKE_${lang}_COMPILER CACHE) 164 | endif() 165 | endif() 166 | endif() 167 | 168 | if(NOT CMAKE_${lang}_COMPILER) 169 | find_program(CMAKE_${lang}_COMPILER NAMES ${binary} PATHS ${COMPILER_SEARCH_PATHS} PATH_SUFFIXES bin REQUIRED) 170 | endif() 171 | 172 | detect_compiler_id() 173 | endfunction() 174 | 175 | find_arm_compiler(ASM arm-none-eabi-gcc) # Use GCC for ASM (solves compiler flag woes for GNU AS) 176 | find_arm_compiler(C arm-none-eabi-gcc) 177 | find_arm_compiler(CXX arm-none-eabi-g++) 178 | 179 | # Set compiler target triples 180 | set(CMAKE_ASM_COMPILER_TARGET arm-none-eabi CACHE INTERNAL "") 181 | set(CMAKE_C_COMPILER_TARGET arm-none-eabi CACHE INTERNAL "") 182 | set(CMAKE_CXX_COMPILER_TARGET arm-none-eabi CACHE INTERNAL "") 183 | 184 | # Find linker 185 | find_program(CMAKE_LINKER NAMES arm-none-eabi-ld PATHS ${COMPILER_SEARCH_PATHS} PATH_SUFFIXES bin REQUIRED) 186 | 187 | # Find C compiler in sysroot 188 | find_program(SYSROOT_COMPILER NAMES arm-none-eabi-gcc PATHS ${COMPILER_SEARCH_PATHS} PATH_SUFFIXES bin REQUIRED NO_CACHE) 189 | unset(COMPILER_SEARCH_PATHS) 190 | 191 | # Find sysroot top-level directory 192 | get_filename_component(SYSROOT_COMPILER "${SYSROOT_COMPILER}" DIRECTORY) 193 | if(SYSROOT_COMPILER MATCHES "/bin/?$") 194 | get_filename_component(SYSROOT_COMPILER "${SYSROOT_COMPILER}" DIRECTORY) 195 | endif() 196 | find_path(SYSROOT_DIRECTORY arm-none-eabi PATHS "${SYSROOT_COMPILER}" PATH_SUFFIXES lib REQUIRED) 197 | unset(SYSROOT_COMPILER) 198 | 199 | # Check for nano libs 200 | execute_process(COMMAND "${CMAKE_C_COMPILER}" -dumpversion OUTPUT_VARIABLE LIBGCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) 201 | find_path(LIBGCC_DIRECTORY "gcc/arm-none-eabi/${LIBGCC_VERSION}" PATHS "${SYSROOT_DIRECTORY}" PATH_SUFFIXES lib) 202 | find_library(CMAKE_NANO c_nano g_nano stdc++_nano supc++_nano PATHS "${LIBGCC_DIRECTORY}/gcc/arm-none-eabi/${LIBGCC_VERSION}") 203 | if(CMAKE_NANO) 204 | set(CMAKE_NANO ON CACHE INTERNAL "") 205 | else() 206 | set(CMAKE_NANO OFF CACHE INTERNAL "") 207 | endif() 208 | unset(LIBGCC_VERSION) 209 | unset(LIBGCC_DIRECTORY CACHE) 210 | 211 | set(CMAKE_SYSROOT "${SYSROOT_DIRECTORY}/arm-none-eabi" CACHE INTERNAL "") 212 | unset(SYSROOT_DIRECTORY CACHE) 213 | 214 | # Set __DEVKITARM__ macro 215 | execute_process(COMMAND "${CMAKE_C_COMPILER}" --version OUTPUT_VARIABLE GNU_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) 216 | if(GNU_VERSION MATCHES "devkitARM") 217 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__DEVKITARM__") 218 | endif() 219 | execute_process(COMMAND "${CMAKE_CXX_COMPILER}" --version OUTPUT_VARIABLE GNU_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) 220 | if(GNU_VERSION MATCHES "devkitARM") 221 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__DEVKITARM__") 222 | endif() 223 | unset(GNU_VERSION) 224 | 225 | # Setup default linker flags 226 | execute_process(COMMAND "${CMAKE_LINKER}" --help OUTPUT_VARIABLE LD_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE) 227 | if(LD_FLAGS MATCHES "[-][-]no[-]warn[-]rwx[-]segments") 228 | set(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-warn-rwx-segments -nostartfiles" CACHE INTERNAL "") 229 | else() 230 | set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles" CACHE INTERNAL "") 231 | endif() 232 | unset(LD_FLAGS) 233 | 234 | # Set system prefix path 235 | get_filename_component(CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY CACHE) 236 | set(CMAKE_SYSTEM_LIBRARY_PATH "${CMAKE_SYSTEM_PREFIX_PATH}/lib" CACHE INTERNAL "") 237 | -------------------------------------------------------------------------------- /lib/multiboot/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | enable_language(ASM) 9 | 10 | add_library(libmultiboot STATIC 11 | crt0.s 12 | multiboot.header.s 13 | ) 14 | set_target_properties(libmultiboot PROPERTIES PREFIX "") 15 | 16 | target_link_options(libmultiboot 17 | PRIVATE 18 | -Wl,--gc-sections 19 | INTERFACE 20 | -T "${CMAKE_CURRENT_LIST_DIR}/multiboot.ld" 21 | $<$:-specs=nano.specs> 22 | -specs=nosys.specs 23 | ) 24 | 25 | execute_process(COMMAND "${CMAKE_C_COMPILER}" --version OUTPUT_VARIABLE GNU_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) 26 | if(NOT GNU_VERSION MATCHES "devkitARM") 27 | enable_language(C) 28 | target_sources(libmultiboot PRIVATE syscalls.c) 29 | endif() 30 | -------------------------------------------------------------------------------- /lib/multiboot/crt0.s: -------------------------------------------------------------------------------- 1 | @=============================================================================== 2 | @ 3 | @ Copyright (C) 2021-2023 gba-toolchain contributors 4 | @ For conditions of distribution and use, see copyright notice in LICENSE.md 5 | @ 6 | @=============================================================================== 7 | 8 | .section .crt0.preheader, "ax" 9 | .arm 10 | .align 2 11 | .global __rom_start 12 | __rom_start: 13 | b __start 14 | 15 | .arm 16 | .align 2 17 | .global __mb_header 18 | 19 | .section .crt0.postheader, "ax" 20 | .arm 21 | .align 2 22 | .global __start 23 | __start: 24 | .global _start 25 | b _start 26 | 27 | .global __mb_info 28 | __mb_info: 29 | @ Boot Mode (overridden) 30 | .byte 0x00 31 | 32 | @ Client ID (overridden) 33 | .byte 0x00 34 | 35 | .global _start 36 | _start: 37 | @ Disable REG_IME (lowest bit = 0) 38 | mov r0, #0x4000000 39 | str r0, [r0, #0x208] 40 | 41 | @ Switch to thumb mode 42 | adr r0, .Lstart + 1 43 | bx r0 44 | 45 | .thumb 46 | .align 1 47 | .Lstart: 48 | @ CpuFastSet fill sbss 49 | ldr r0, =__zero_word 50 | ldr r1, =__sbss_start 51 | ldr r2, =__sbss_swi0c 52 | swi #0xc 53 | 54 | @ CpuFastSet fill bss 55 | ldr r0, =__zero_word 56 | ldr r1, =__bss_start 57 | ldr r2, =__bss_swi0c 58 | swi #0xc 59 | 60 | @ CpuFastSet copy iwram 61 | ldr r0, =__iwram_lma 62 | ldr r1, =__iwram_start 63 | ldr r2, =__iwram_swi0c 64 | swi #0xc 65 | 66 | @ Using r4-r5 to avoid pushing r0-r3 67 | @ init immediately follows preinit so we can join these arrays 68 | ldr r4, =__preinit_array_start 69 | ldr r5, =__init_array_end 70 | bl __array_call 71 | 72 | @ argc, argv 73 | mov r0, #0 74 | mov r1, #0 75 | bl main 76 | @ Fallthrough 77 | 78 | .thumb 79 | .global exit 80 | exit: 81 | ldr r1, =#0x4000208 82 | str r1, [r1] @ Disable REG_IME (lowest bit = 0) 83 | 84 | mov r1, #0 @ NULL 85 | push {r0} @ Push exit code 86 | bl __call_exitprocs 87 | pop {r0} 88 | 89 | @ Using r4-r5 to avoid pushing r0-r3 90 | ldr r4, =__fini_array_start 91 | ldr r5, =__fini_array_end 92 | bl __array_call 93 | @ Fallthrough 94 | 95 | .thumb 96 | .global _Exit 97 | _Exit: 98 | ldr r1, =#0x4000208 99 | str r1, [r1] @ Disable REG_IME (lowest bit = 0) 100 | 101 | @ Loop 102 | b _start 103 | 104 | .thumb 105 | __array_call: 106 | push {lr} 107 | cmp r4, r5 108 | beq .Larray_skip 109 | .Larray_loop: 110 | ldm r4!, {r0} 111 | bl .Larray_bx 112 | cmp r4, r5 113 | bne .Larray_loop 114 | .Larray_skip: 115 | pop {r0} 116 | .Larray_bx: 117 | bx r0 118 | 119 | @ Reference a symbol from syscalls.c to keep 120 | .global _getpid 121 | -------------------------------------------------------------------------------- /lib/multiboot/multiboot.header.s: -------------------------------------------------------------------------------- 1 | @=============================================================================== 2 | @ 3 | @ Copyright (C) 2021-2023 gba-toolchain contributors 4 | @ For conditions of distribution and use, see copyright notice in LICENSE.md 5 | @ 6 | @=============================================================================== 7 | 8 | .section .mb.header 9 | 10 | .align 0 11 | .global __mb_header 12 | __mb_header: 13 | 14 | .byte 0x24, 0xFF, 0xAE, 0x51, 0x69, 0x9A, 0xA2, 0x21 15 | .byte 0x3D, 0x84, 0x82, 0x0A, 0x84, 0xE4, 0x09, 0xAD 16 | .byte 0x11, 0x24, 0x8B, 0x98, 0xC0, 0x81, 0x7F, 0x21 17 | .byte 0xA3, 0x52, 0xBE, 0x19, 0x93, 0x09, 0xCE, 0x20 18 | .byte 0x10, 0x46, 0x4A, 0x4A, 0xF8, 0x27, 0x31, 0xEC 19 | .byte 0x58, 0xC7, 0xE8, 0x33, 0x82, 0xE3, 0xCE, 0xBF 20 | .byte 0x85, 0xF4, 0xDF, 0x94, 0xCE, 0x4B, 0x09, 0xC1 21 | .byte 0x94, 0x56, 0x8A, 0xC0, 0x13, 0x72, 0xA7, 0xFC 22 | .byte 0x9F, 0x84, 0x4D, 0x73, 0xA3, 0xCA, 0x9A, 0x61 23 | .byte 0x58, 0x97, 0xA3, 0x27, 0xFC, 0x03, 0x98, 0x76 24 | .byte 0x23, 0x1D, 0xC7, 0x61, 0x03, 0x04, 0xAE, 0x56 25 | .byte 0xBF, 0x38, 0x84, 0x00, 0x40, 0xA7, 0x0E, 0xFD 26 | .byte 0xFF, 0x52, 0xFE, 0x03, 0x6F, 0x95, 0x30, 0xF1 27 | .byte 0x97, 0xFB, 0xC0, 0x85, 0x60, 0xD6, 0x80, 0x25 28 | .byte 0xA9, 0x63, 0xBE, 0x03, 0x01, 0x4E, 0x38, 0xE2 29 | .byte 0xF9, 0xA2, 0x34, 0xFF, 0xBB, 0x3E, 0x03, 0x44 30 | .byte 0x78, 0x00, 0x90, 0xCB, 0x88, 0x11, 0x3A, 0x94 31 | .byte 0x65, 0xC0, 0x7C, 0x63, 0x87, 0xF0, 0x3C, 0xAF 32 | .byte 0xD6, 0x25, 0xE4, 0x8B, 0x38, 0x0A, 0xAC, 0x72 33 | .byte 0x21, 0xD4, 0xF8, 0x07 34 | 35 | @ ASCII game title [12] 36 | .ascii "\0\0\0\0\0\0\0\0\0\0\0\0" 37 | 38 | @ ASCII game code [4] 39 | .ascii "\0\0\0\0" 40 | 41 | @ ASCII maker code [2] 42 | .ascii "\0\0" 43 | 44 | @ Fixed value 45 | .byte 0x96 46 | 47 | @ Target device (0 = GBA) 48 | .byte 0x00 49 | 50 | @ Debug flags [4] 51 | .word 0x00000000 52 | 53 | @ Dynamic shared object handle set to zero word (nullptr) 54 | .global __dso_handle 55 | __dso_handle: 56 | .global __zero_word 57 | __zero_word: 58 | .word 0x00000000 59 | 60 | @ Software version 61 | .byte 0x00 62 | 63 | @ Checksum (calculated as 0x00 - 0x96 - 0x19) 64 | .byte 0x51 65 | 66 | @ Unused [2] 67 | .hword 0x0000 68 | -------------------------------------------------------------------------------- /lib/multiboot/multiboot.ld: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Copyright (C) 2021-2023 gba-toolchain contributors 5 | For conditions of distribution and use, see copyright notice in LICENSE.md 6 | 7 | =============================================================================== 8 | */ 9 | 10 | OUTPUT_FORMAT("elf32-littlearm") 11 | OUTPUT_ARCH(arm) 12 | ENTRY(_start) 13 | 14 | MEMORY { 15 | ewram : ORIGIN = 0x2000000, LENGTH = 256K 16 | iwram : ORIGIN = 0x3000000, LENGTH = 32K 17 | } 18 | 19 | __sp_irq = ORIGIN(iwram) + LENGTH(iwram) - 0x60; 20 | __sp_usr = __sp_irq - 0xA0; 21 | __sp_usr_reserve = 0x200; 22 | 23 | PROVIDE_HIDDEN(__eheap_end = ORIGIN(ewram) + LENGTH(ewram)); 24 | PROVIDE_HIDDEN(__iwram_start__ = ORIGIN(iwram)); 25 | PROVIDE_HIDDEN(__iwram_top = ORIGIN(iwram) + LENGTH(iwram)); 26 | 27 | SECTIONS { 28 | . = ORIGIN(ewram); 29 | 30 | .crt0 : { 31 | KEEP(*(.crt0.preheader)) 32 | KEEP(*(.mb.header)) 33 | KEEP(*(.crt0.postheader)) 34 | 35 | PROVIDE_HIDDEN(__sbss_swi0c = ABSOLUTE(((__sbss_end - __sbss_start) / 4) | (1 << 24))); 36 | PROVIDE_HIDDEN(__bss_swi0c = ABSOLUTE(((__bss_end - __bss_start) / 4) | (1 << 24))); 37 | 38 | PROVIDE_HIDDEN(__iwram_swi0c = ABSOLUTE((__iwram_lma_end - __iwram_lma) / 4)); 39 | } > ewram 40 | 41 | .init_array : { 42 | PROVIDE_HIDDEN(__preinit_array_start = .); 43 | KEEP(*(.preinit_array .preinit_array.*)) 44 | PROVIDE_HIDDEN(__preinit_array_end = .); 45 | 46 | PROVIDE_HIDDEN(__init_array_start = .); 47 | KEEP(*(.init_array .init_array.*)) 48 | PROVIDE_HIDDEN(__init_array_end = .); 49 | } > ewram 50 | 51 | .fini_array : { 52 | PROVIDE_HIDDEN(__fini_array_start = .); 53 | KEEP(*(.fini_array .fini_array.*)) 54 | PROVIDE_HIDDEN(__fini_array_end = .); 55 | } > ewram 56 | 57 | .ARM.exidx : { 58 | PROVIDE_HIDDEN(__exidx_start = .); 59 | *(.ARM.exidx.* .gnu.linkonce.armexidx.*) 60 | PROVIDE_HIDDEN(__exidx_end = .); 61 | } > ewram 62 | 63 | .sbss(NOLOAD) : ALIGN(32) { 64 | PROVIDE_HIDDEN(__sbss_start = ABSOLUTE(.)); 65 | *(.sbss .sbss.*) 66 | . = ALIGN(32); 67 | PROVIDE_HIDDEN(__sbss_end = ABSOLUTE(.)); 68 | PROVIDE_HIDDEN(__sbss_end__ = __sbss_end); 69 | } > ewram 70 | 71 | PROVIDE_HIDDEN(__iwram_overlay_start = ORIGIN(iwram)); 72 | PROVIDE_HIDDEN(__iwram_overlay_lma = ALIGN(4)); 73 | . = __iwram_overlay_lma; 74 | 75 | OVERLAY : NOCROSSREFS AT(__iwram_overlay_lma) { 76 | .iwram0 { *(.iwram0 .iwram0.*) *.iwram0.*(.text .text.*) } 77 | .iwram1 { *(.iwram1 .iwram1.*) *.iwram1.*(.text .text.*) } 78 | .iwram2 { *(.iwram2 .iwram2.*) *.iwram2.*(.text .text.*) } 79 | .iwram3 { *(.iwram3 .iwram3.*) *.iwram3.*(.text .text.*) } 80 | .iwram4 { *(.iwram4 .iwram4.*) *.iwram4.*(.text .text.*) } 81 | .iwram5 { *(.iwram5 .iwram5.*) *.iwram5.*(.text .text.*) } 82 | .iwram6 { *(.iwram6 .iwram6.*) *.iwram6.*(.text .text.*) } 83 | .iwram7 { *(.iwram7 .iwram7.*) *.iwram7.*(.text .text.*) } 84 | .iwram8 { *(.iwram8 .iwram8.*) *.iwram8.*(.text .text.*) } 85 | .iwram9 { *(.iwram9 .iwram9.*) *.iwram9.*(.text .text.*) } 86 | } > iwram 87 | 88 | PROVIDE_HIDDEN(__iwram_start = ALIGN(4)); 89 | PROVIDE_HIDDEN(__iwram_lma = ALIGN(__iwram_overlay_lma + (. - __iwram_overlay_start), 32)); 90 | 91 | .iwram : AT(__iwram_lma) { 92 | KEEP(*(SORT(.iwram.sorted.*))) 93 | *(.iwram .iwram.*) 94 | *.iwram.*(.data .data.* .text .text.*) 95 | *(.data .data.* .gnu.linkonce.d.*) 96 | . = ALIGN(32); 97 | } > iwram 98 | 99 | PROVIDE_HIDDEN(__iwram_lma_end = ALIGN(__iwram_lma + (. - __iwram_start), 4)); 100 | 101 | .bss(NOLOAD) : ALIGN(32) { 102 | PROVIDE_HIDDEN(__bss_start = ABSOLUTE(.)); 103 | *(.bss .bss.*) 104 | *(COMMON) 105 | . = ALIGN(32); 106 | PROVIDE_HIDDEN(__bss_end = ABSOLUTE(.)); 107 | } > iwram 108 | 109 | . = __iwram_lma_end; 110 | 111 | .text : AT(__iwram_lma_end) { 112 | EXCLUDE_FILE(*.iwram.* *.iwram[0-9].*) *(.text .text.* .gnu.linkonce.t.*) 113 | } 114 | 115 | .rodata : { 116 | *(.rodata .rodata.* .gnu.linkonce.r.*) 117 | } 118 | 119 | PROVIDE_HIDDEN(end = ALIGN(__iwram_lma_end + SIZEOF(.text) + SIZEOF(.rodata), 32)); 120 | PROVIDE_HIDDEN(__end__ = end); 121 | PROVIDE_HIDDEN(__eheap_start = __end__); 122 | } 123 | -------------------------------------------------------------------------------- /lib/multiboot/syscalls.c: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Copyright (C) 2021-2023 gba-toolchain contributors 5 | For conditions of distribution and use, see copyright notice in LICENSE.md 6 | 7 | =============================================================================== 8 | */ 9 | 10 | /* Stubs based on https://sourceware.org/newlib/libc.html */ 11 | 12 | #include 13 | #include 14 | 15 | #undef errno 16 | extern int errno; 17 | 18 | static int stub(void) { 19 | errno = ENOSYS; 20 | return -1; 21 | } 22 | 23 | #pragma clang diagnostic push 24 | #pragma ide diagnostic ignored "bugprone-reserved-identifier" 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wattribute-alias" 27 | 28 | int _open(const char *file, int flags, int mode) __attribute__((alias("stub"))); 29 | 30 | int _close(int file) __attribute__((alias("stub"))); 31 | 32 | int _fstat(int file, struct stat *st) __attribute__((alias("stub"))); 33 | 34 | int _getpid(void) __attribute__((alias("stub"))); 35 | 36 | int _isatty(int file) __attribute__((alias("stub"))); 37 | 38 | int _kill(int pid, int sig) __attribute__((alias("stub"))); 39 | 40 | int _lseek(int file, int ptr, int dir) __attribute__((alias("stub"))); 41 | 42 | int _read(int file, char *ptr, int len) __attribute__((alias("stub"))); 43 | 44 | int _write(int file, char *ptr, int len) __attribute__((alias("stub"))); 45 | 46 | #pragma GCC diagnostic pop 47 | #pragma clang diagnostic pop 48 | -------------------------------------------------------------------------------- /lib/rom/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================== 2 | # 3 | # Copyright (C) 2021-2023 gba-toolchain contributors 4 | # For conditions of distribution and use, see copyright notice in LICENSE.md 5 | # 6 | #=============================================================================== 7 | 8 | enable_language(ASM) 9 | 10 | add_library(librom STATIC 11 | crt0.s 12 | rom.header.s 13 | ) 14 | set_target_properties(librom PROPERTIES PREFIX "") 15 | 16 | target_link_options(librom 17 | PRIVATE 18 | -Wl,--gc-sections 19 | INTERFACE 20 | -T "${CMAKE_CURRENT_LIST_DIR}/rom.ld" 21 | $<$:-specs=nano.specs> 22 | -specs=nosys.specs 23 | ) 24 | 25 | execute_process(COMMAND "${CMAKE_C_COMPILER}" --version OUTPUT_VARIABLE GNU_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) 26 | if(NOT GNU_VERSION MATCHES "devkitARM") 27 | enable_language(C) 28 | target_sources(librom PRIVATE syscalls.c) 29 | endif() 30 | -------------------------------------------------------------------------------- /lib/rom/crt0.s: -------------------------------------------------------------------------------- 1 | @=============================================================================== 2 | @ 3 | @ Copyright (C) 2021-2023 gba-toolchain contributors 4 | @ For conditions of distribution and use, see copyright notice in LICENSE.md 5 | @ 6 | @=============================================================================== 7 | 8 | .section .crt0.preheader, "ax" 9 | .arm 10 | .align 2 11 | .global __start 12 | __start: 13 | b _start 14 | 15 | .global __cart_header 16 | 17 | .section .crt0.postheader, "ax" 18 | .arm 19 | .align 2 20 | .global _start 21 | _start: 22 | @ Disable REG_IME (lowest bit = 0) 23 | mov r0, #0x4000000 24 | str r0, [r0, #0x208] 25 | 26 | @ Switch to thumb mode 27 | adr r0, .Lstart + 1 28 | bx r0 29 | 30 | .thumb 31 | .align 1 32 | .Lstart: 33 | @ CpuFastSet fill sbss 34 | ldr r0, =__zero_word 35 | ldr r1, =__sbss_start 36 | ldr r2, =__sbss_swi0c 37 | swi #0xc 38 | 39 | @ CpuFastSet fill bss 40 | ldr r0, =__zero_word 41 | ldr r1, =__bss_start 42 | ldr r2, =__bss_swi0c 43 | swi #0xc 44 | 45 | @ CpuFastSet copy ewram 46 | ldr r0, =__ewram_lma 47 | ldr r1, =__ewram_start 48 | ldr r2, =__ewram_swi0c 49 | swi #0xc 50 | 51 | @ CpuFastSet copy iwram 52 | ldr r0, =__iwram_lma 53 | ldr r1, =__iwram_start 54 | ldr r2, =__iwram_swi0c 55 | swi #0xc 56 | 57 | @ Using r4-r5 to avoid pushing r0-r3 58 | @ init immediately follows preinit so we can join these arrays 59 | ldr r4, =__preinit_array_start 60 | ldr r5, =__init_array_end 61 | bl __array_call 62 | 63 | @ argc, argv 64 | mov r0, #0 65 | mov r1, #0 66 | bl main 67 | @ Fallthrough 68 | 69 | .thumb 70 | .global exit 71 | exit: 72 | ldr r1, =#0x4000208 73 | str r1, [r1] @ Disable REG_IME (lowest bit = 0) 74 | 75 | mov r1, #0 @ NULL 76 | push {r0} @ Push exit code 77 | bl __call_exitprocs 78 | pop {r0} 79 | 80 | .global _fini 81 | _fini: 82 | @ Using r4-r5 to avoid pushing r0-r3 83 | ldr r4, =__fini_array_start 84 | ldr r5, =__fini_array_end 85 | bl __array_call 86 | @ Fallthrough 87 | 88 | .thumb 89 | .global _Exit 90 | _Exit: 91 | ldr r1, =#0x4000208 92 | str r1, [r1] @ Disable REG_IME (lowest bit = 0) 93 | 94 | @ SoftReset 95 | swi #0x0 96 | 97 | .thumb 98 | __array_call: 99 | push {lr} 100 | cmp r4, r5 101 | beq .Larray_skip 102 | .Larray_loop: 103 | ldm r4!, {r0} 104 | bl .Larray_bx 105 | cmp r4, r5 106 | bne .Larray_loop 107 | .Larray_skip: 108 | pop {r0} 109 | .Larray_bx: 110 | bx r0 111 | 112 | @ Reference a symbol from syscalls.c to keep 113 | .global _getpid 114 | -------------------------------------------------------------------------------- /lib/rom/rom.header.s: -------------------------------------------------------------------------------- 1 | @=============================================================================== 2 | @ 3 | @ Copyright (C) 2021-2023 gba-toolchain contributors 4 | @ For conditions of distribution and use, see copyright notice in LICENSE.md 5 | @ 6 | @=============================================================================== 7 | 8 | .section .cart.header 9 | 10 | .align 0 11 | .global __cart_header 12 | __cart_header: 13 | 14 | .byte 0x24, 0xFF, 0xAE, 0x51, 0x69, 0x9A, 0xA2, 0x21 15 | .byte 0x3D, 0x84, 0x82, 0x0A, 0x84, 0xE4, 0x09, 0xAD 16 | .byte 0x11, 0x24, 0x8B, 0x98, 0xC0, 0x81, 0x7F, 0x21 17 | .byte 0xA3, 0x52, 0xBE, 0x19, 0x93, 0x09, 0xCE, 0x20 18 | .byte 0x10, 0x46, 0x4A, 0x4A, 0xF8, 0x27, 0x31, 0xEC 19 | .byte 0x58, 0xC7, 0xE8, 0x33, 0x82, 0xE3, 0xCE, 0xBF 20 | .byte 0x85, 0xF4, 0xDF, 0x94, 0xCE, 0x4B, 0x09, 0xC1 21 | .byte 0x94, 0x56, 0x8A, 0xC0, 0x13, 0x72, 0xA7, 0xFC 22 | .byte 0x9F, 0x84, 0x4D, 0x73, 0xA3, 0xCA, 0x9A, 0x61 23 | .byte 0x58, 0x97, 0xA3, 0x27, 0xFC, 0x03, 0x98, 0x76 24 | .byte 0x23, 0x1D, 0xC7, 0x61, 0x03, 0x04, 0xAE, 0x56 25 | .byte 0xBF, 0x38, 0x84, 0x00, 0x40, 0xA7, 0x0E, 0xFD 26 | .byte 0xFF, 0x52, 0xFE, 0x03, 0x6F, 0x95, 0x30, 0xF1 27 | .byte 0x97, 0xFB, 0xC0, 0x85, 0x60, 0xD6, 0x80, 0x25 28 | .byte 0xA9, 0x63, 0xBE, 0x03, 0x01, 0x4E, 0x38, 0xE2 29 | .byte 0xF9, 0xA2, 0x34, 0xFF, 0xBB, 0x3E, 0x03, 0x44 30 | .byte 0x78, 0x00, 0x90, 0xCB, 0x88, 0x11, 0x3A, 0x94 31 | .byte 0x65, 0xC0, 0x7C, 0x63, 0x87, 0xF0, 0x3C, 0xAF 32 | .byte 0xD6, 0x25, 0xE4, 0x8B, 0x38, 0x0A, 0xAC, 0x72 33 | .byte 0x21, 0xD4, 0xF8, 0x07 34 | 35 | @ ASCII game title [12] 36 | .ascii "\0\0\0\0\0\0\0\0\0\0\0\0" 37 | 38 | @ ASCII game code [4] 39 | .ascii "\0\0\0\0" 40 | 41 | @ ASCII maker code [2] 42 | .ascii "\0\0" 43 | 44 | @ Fixed value 45 | .byte 0x96 46 | 47 | @ Target device (0 = GBA) 48 | .byte 0x00 49 | 50 | @ Debug flags [4] 51 | .word 0x00000000 52 | 53 | @ Dynamic shared object handle set to zero word (nullptr) 54 | .global __dso_handle 55 | __dso_handle: 56 | .global __zero_word 57 | __zero_word: 58 | .word 0x00000000 59 | 60 | @ Software version 61 | .byte 0x00 62 | 63 | @ Checksum (calculated as 0x00 - 0x96 - 0x19) 64 | .byte 0x51 65 | 66 | @ Unused [6] 67 | .hword 0x0000 68 | .word 0x00000000 69 | 70 | @ GPIO 71 | .word 0x00000000 72 | .word 0x00000000 73 | -------------------------------------------------------------------------------- /lib/rom/rom.ld: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Copyright (C) 2021-2023 gba-toolchain contributors 5 | For conditions of distribution and use, see copyright notice in LICENSE.md 6 | 7 | =============================================================================== 8 | */ 9 | 10 | OUTPUT_FORMAT("elf32-littlearm") 11 | OUTPUT_ARCH(arm) 12 | ENTRY(__start) 13 | 14 | MEMORY { 15 | ewram : ORIGIN = 0x2000000, LENGTH = 256K 16 | iwram : ORIGIN = 0x3000000, LENGTH = 32K 17 | rom : ORIGIN = 0x8000000, LENGTH = 32M 18 | } 19 | 20 | __sp_irq = ORIGIN(iwram) + LENGTH(iwram) - 0x60; 21 | __sp_usr = __sp_irq - 0xA0; 22 | __sp_usr_reserve = 0x200; 23 | 24 | PROVIDE_HIDDEN(__eheap_end = ORIGIN(ewram) + LENGTH(ewram)); 25 | PROVIDE_HIDDEN(__iwram_start__ = ORIGIN(iwram)); 26 | PROVIDE_HIDDEN(__iwram_top = ORIGIN(iwram) + LENGTH(iwram)); 27 | 28 | SECTIONS { 29 | . = ORIGIN(rom); 30 | 31 | .crt0 : { 32 | KEEP(*(.crt0.preheader)) 33 | KEEP(*(.cart.header)) 34 | KEEP(*(.cart.backup)) 35 | KEEP(*(.crt0.postheader)) 36 | 37 | PROVIDE_HIDDEN(__sbss_swi0c = ABSOLUTE((SIZEOF(.sbss) / 4) | (1 << 24))); 38 | PROVIDE_HIDDEN(__bss_swi0c = ABSOLUTE((SIZEOF(.bss) / 4) | (1 << 24))); 39 | 40 | PROVIDE_HIDDEN(__ewram_swi0c = ABSOLUTE(SIZEOF(.ewram) / 4)); 41 | PROVIDE_HIDDEN(__iwram_swi0c = ABSOLUTE(SIZEOF(.iwram) / 4)); 42 | } > rom 43 | 44 | .init_array : { 45 | PROVIDE_HIDDEN(__preinit_array_start = .); 46 | KEEP(*(.preinit_array .preinit_array.*)) 47 | PROVIDE_HIDDEN(__preinit_array_end = .); 48 | 49 | PROVIDE_HIDDEN(__init_array_start = .); 50 | KEEP(*(.init_array .init_array.*)) 51 | PROVIDE_HIDDEN(__init_array_end = .); 52 | } > rom 53 | 54 | .fini_array : { 55 | PROVIDE_HIDDEN(__fini_array_start = .); 56 | KEEP(*(.fini_array .fini_array.*)) 57 | PROVIDE_HIDDEN(__fini_array_end = .); 58 | } > rom 59 | 60 | .ARM.exidx : { 61 | PROVIDE_HIDDEN(__exidx_start = .); 62 | *(.ARM.exidx.* .gnu.linkonce.armexidx.*) 63 | PROVIDE_HIDDEN(__exidx_end = .); 64 | } > rom 65 | 66 | PROVIDE_HIDDEN(__ewram_overlay_start = ORIGIN(ewram)); 67 | PROVIDE_HIDDEN(__ewram_overlay_lma = ALIGN(4)); 68 | . = __ewram_overlay_lma; 69 | 70 | OVERLAY : NOCROSSREFS AT(__ewram_overlay_lma) { 71 | .ewram0 { *(.ewram0 .ewram0.*) *.ewram0.*(.text .text.*) } 72 | .ewram1 { *(.ewram1 .ewram1.*) *.ewram1.*(.text .text.*) } 73 | .ewram2 { *(.ewram2 .ewram2.*) *.ewram2.*(.text .text.*) } 74 | .ewram3 { *(.ewram3 .ewram3.*) *.ewram3.*(.text .text.*) } 75 | .ewram4 { *(.ewram4 .ewram4.*) *.ewram4.*(.text .text.*) } 76 | .ewram5 { *(.ewram5 .ewram5.*) *.ewram5.*(.text .text.*) } 77 | .ewram6 { *(.ewram6 .ewram6.*) *.ewram6.*(.text .text.*) } 78 | .ewram7 { *(.ewram7 .ewram7.*) *.ewram7.*(.text .text.*) } 79 | .ewram8 { *(.ewram8 .ewram8.*) *.ewram8.*(.text .text.*) } 80 | .ewram9 { *(.ewram9 .ewram9.*) *.ewram9.*(.text .text.*) } 81 | } > ewram 82 | 83 | PROVIDE_HIDDEN(__ewram_start = ALIGN(4)); 84 | PROVIDE_HIDDEN(__ewram_lma = ALIGN(__ewram_overlay_lma + (. - __ewram_overlay_start), 4)); 85 | 86 | .ewram : AT(__ewram_lma) ALIGN(32) { 87 | KEEP(*(SORT(.ewram.sorted.*))) 88 | *(.ewram .ewram.*) 89 | *.ewram.*(.data .data.* .text .text.*) 90 | . = ALIGN(32); 91 | } > ewram 92 | 93 | PROVIDE_HIDDEN(__ewram_lma_end = ALIGN(__ewram_lma + (. - __ewram_start), 4)); 94 | 95 | .sbss(NOLOAD) : ALIGN(32) { 96 | PROVIDE_HIDDEN(__sbss_start = ABSOLUTE(.)); 97 | *(.sbss .sbss.*) 98 | . = ALIGN(32); 99 | PROVIDE_HIDDEN(__sbss_end = ABSOLUTE(.)); 100 | PROVIDE_HIDDEN(__sbss_end__ = __sbss_end); 101 | } > ewram 102 | 103 | PROVIDE_HIDDEN(end = ALIGN(__sbss_end, 4)); 104 | PROVIDE_HIDDEN(__end__ = end); 105 | PROVIDE_HIDDEN(__eheap_start = __end__); 106 | 107 | PROVIDE_HIDDEN(__iwram_overlay_start = ORIGIN(iwram)); 108 | PROVIDE_HIDDEN(__iwram_overlay_lma = __ewram_lma_end); 109 | . = __iwram_overlay_lma; 110 | 111 | OVERLAY : NOCROSSREFS AT(__iwram_overlay_lma) { 112 | .iwram0 { *(.iwram0 .iwram0.*) *.iwram0.*(.text .text.*) } 113 | .iwram1 { *(.iwram1 .iwram1.*) *.iwram1.*(.text .text.*) } 114 | .iwram2 { *(.iwram2 .iwram2.*) *.iwram2.*(.text .text.*) } 115 | .iwram3 { *(.iwram3 .iwram3.*) *.iwram3.*(.text .text.*) } 116 | .iwram4 { *(.iwram4 .iwram4.*) *.iwram4.*(.text .text.*) } 117 | .iwram5 { *(.iwram5 .iwram5.*) *.iwram5.*(.text .text.*) } 118 | .iwram6 { *(.iwram6 .iwram6.*) *.iwram6.*(.text .text.*) } 119 | .iwram7 { *(.iwram7 .iwram7.*) *.iwram7.*(.text .text.*) } 120 | .iwram8 { *(.iwram8 .iwram8.*) *.iwram8.*(.text .text.*) } 121 | .iwram9 { *(.iwram9 .iwram9.*) *.iwram9.*(.text .text.*) } 122 | } > iwram 123 | 124 | PROVIDE_HIDDEN(__iwram_start = ALIGN(4)); 125 | PROVIDE_HIDDEN(__iwram_lma = ALIGN(__iwram_overlay_lma + (. - __iwram_overlay_start), 32)); 126 | 127 | .iwram : AT(__iwram_lma) { 128 | KEEP(*(SORT(.iwram.sorted.*))) 129 | *(.iwram .iwram.*) 130 | *.iwram.*(.data .data.* .text .text.*) 131 | *(.data .data.* .gnu.linkonce.d.*) 132 | . = ALIGN(32); 133 | } > iwram 134 | 135 | PROVIDE_HIDDEN(__iwram_lma_end = ALIGN(__iwram_lma + SIZEOF(.iwram), 4)); 136 | 137 | .bss(NOLOAD) : ALIGN(32) { 138 | PROVIDE_HIDDEN(__bss_start = ABSOLUTE(.)); 139 | *(.bss .bss.*) 140 | *(COMMON) 141 | . = ALIGN(32); 142 | PROVIDE_HIDDEN(__bss_end = ABSOLUTE(.)); 143 | } > iwram 144 | 145 | . = __iwram_lma_end; 146 | 147 | .text : AT(__iwram_lma_end) { 148 | EXCLUDE_FILE(*.iwram.* *.ewram.* *.iwram[0-9].* *.ewram[0-9].*) *(.text .text.* .gnu.linkonce.t.*) 149 | . = ALIGN(4); 150 | } 151 | 152 | .rodata : { 153 | *(.rodata .rodata.* .gnu.linkonce.r.*) 154 | } 155 | 156 | PROVIDE_HIDDEN(__rom_end = ALIGN(256)); 157 | } 158 | -------------------------------------------------------------------------------- /lib/rom/syscalls.c: -------------------------------------------------------------------------------- 1 | /* 2 | =============================================================================== 3 | 4 | Copyright (C) 2021-2023 gba-toolchain contributors 5 | For conditions of distribution and use, see copyright notice in LICENSE.md 6 | 7 | =============================================================================== 8 | */ 9 | 10 | /* Stubs based on https://sourceware.org/newlib/libc.html */ 11 | 12 | #include 13 | #include 14 | 15 | #undef errno 16 | extern int errno; 17 | 18 | static int stub(void) { 19 | errno = ENOSYS; 20 | return -1; 21 | } 22 | 23 | #pragma clang diagnostic push 24 | #pragma ide diagnostic ignored "bugprone-reserved-identifier" 25 | #pragma GCC diagnostic push 26 | #pragma GCC diagnostic ignored "-Wattribute-alias" 27 | 28 | int _open(const char *file, int flags, int mode) __attribute__((alias("stub"))); 29 | 30 | int _close(int file) __attribute__((alias("stub"))); 31 | 32 | int _fstat(int file, struct stat *st) __attribute__((alias("stub"))); 33 | 34 | int _getpid(void) __attribute__((alias("stub"))); 35 | 36 | int _isatty(int file) __attribute__((alias("stub"))); 37 | 38 | int _kill(int pid, int sig) __attribute__((alias("stub"))); 39 | 40 | int _lseek(int file, int ptr, int dir) __attribute__((alias("stub"))); 41 | 42 | int _read(int file, char *ptr, int len) __attribute__((alias("stub"))); 43 | 44 | int _write(int file, char *ptr, int len) __attribute__((alias("stub"))); 45 | 46 | #pragma GCC diagnostic pop 47 | #pragma clang diagnostic pop 48 | --------------------------------------------------------------------------------