├── .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 |
--------------------------------------------------------------------------------