Importing assets
Importing your graphic and audio files into a GBA game can be annoying, but with Butano and this guide you will be good to go.
GBA ROMs by themselves don't include a file system, so you can't put a couple of *.bmp
files into a folder and expect to read them directly from the GBA side.
This means that all the game's data has to be added directly to the binary. Don't worry, because Butano build system does this for you. When you drop a file into an assets folder, Butano:
- Generates a GBA-friendly version of it.
- Inserts it into the ROM.
- Creates a C++ header into the
build
folder containing the required information to use the assets with ease.
Let's see how to import image and audio files.
Images
By default image files go into the graphics
folder of your project.
Butano for now is a little finicky about the images it likes, sorry.
The required image format is the following:
- BMP without compression or color space information.
- 16 or 256 colors only.
- The first color in the color palette is the transparent one, so in most cases it will not be shown on screen.
If you get an invalid header size
error when importing a *.bmp
file, it probably means that the image format is not supported.
If you are using GIMP for your images, remember to disable color space information:
However, the recommended tool to ensure that your images are compatible with Butano is Usenti:
Usenti is a simple bitmap editor for paletted images, it is like the good old Paint but with various palette/color manipulation tools.
Any program that can generate indexed *.bmp
files without weird headers should work. However:
- Usenti works with 15BPP (bits per pixel) colors, like the GBA and unlike most other popular image editors, which work with 24BPP or 32BPP colors. BPP reduction destroys some color gradients, so the images generated by Usenti are closer to what a GBA can display.
- Usenti is powered by grit, the tool used by Butano to convert images to GBA friendly data. grit doesn't support some
*.bmp
features like compression or some weird headers, so if Usenti displays a*.bmp
file without issues, grit should be able to process it successfully.
If you are not going to use Usenti for your images, at least try to check them with it when they are not displayed as expected.
A single *.bmp
file is not enough to display graphics on the GBA. You must accompany it with a *.json
file with the same name specifying if it is a sprite or a background and some more info.
Let's see how to do it.
Sprites
An image file can contain multiple sprite images. If it only contains one sprite image, its size must be one of the specified by bn::
Multiple sprite images are allowed by layering them down on the vertical axis:
An example of the *.json
files required for sprites is the following:
{ "type": "sprite" }
The fields for sprites are the following:
"type"
: must be"sprite"
for sprites."height"
: optional field which specifies the height of each sprite image in pixels. For example, if the specified height is 32, an image with 128 pixels of height contains 4 sprite images."bpp_mode"
: optional field which specifies the bits per pixel of the sprite:"bpp_8"
: up to 256 colors."bpp_4"
: up to 16 colors.
"colors_count"
: optional field which specifies the sprite palette size [1..256]."tiles_compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"palette_compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"compression"
: optional field which specifies the compression of the tiles and the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_sprite_items_image.h
is generated in the build
folder.
You can use this header to create a sprite with only one line of C++ code:
#include "bn_sprite_items_image.h" bn::sprite_ptr sprite = bn::sprite_items::image.create_sprite(0, 0);
Sprite tiles
An image file can contain multiple sprite tile sets. If it only contains one sprite tile set, the size of the image must be one of the specified by bn::
Multiple sprite tile sets are allowed by layering them down on the vertical axis:
An example of the *.json
files required for sprite tiles is the following:
{ "type": "sprite_tiles" }
The fields for sprite tiles are the following:
"type"
: must be"sprite_tiles"
for sprite tiles."height"
: optional field which specifies the height of each sprite tile set in pixels. For example, if the specified height is 32, an image with 128 pixels of height contains 4 sprite tile sets."bpp_mode"
: optional field which specifies the bits per pixel of the sprite tiles:"bpp_8"
: up to 256 colors."bpp_4"
: up to 16 colors.
"colors_count"
: optional field which specifies the sprite palette size [1..256]."compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_sprite_tiles_items_image.h
is generated in the build
folder.
You can use this header to create sprite tiles with only one line of C++ code:
#include "bn_sprite_tiles_items_image.h" bn::sprite_tiles_ptr sprite_tiles = bn::sprite_tiles_items::image.create_tiles();
Sprite palettes
An example of the *.json
files required for sprite palettes is the following:
{ "type": "sprite_palette" }
The fields for sprite palettes are the following:
"type"
: must be"sprite_palette"
for sprite palettes."bpp_mode"
: optional field which specifies the bits per pixel of the sprite palette:"bpp_8"
: up to 256 colors."bpp_4"
: up to 16 colors.
"colors_count"
: optional field which specifies the sprite palette size [1..256]."compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_sprite_palette_items_image.h
is generated in the build
folder.
You can use this header to create a sprite palette with only one line of C++ code:
#include "bn_sprite_palette_items_image.h" bn::sprite_palette_ptr sprite_palette = bn::sprite_palette_items::image.create_palette();
Regular backgrounds
An image file can contain multiple regular backgrounds. The size of a small regular background (which are faster) must be 256x256, 256x512, 512x256 or 512x512 pixels. Big regular backgrounds are slower CPU wise, but can have any width or height multiple of 256 pixels.
Multiple regular background images are allowed by layering them down on the vertical axis:
An example of the *.json
files required for regular backgrounds is the following:
{ "type": "regular_bg" }
The fields for regular backgrounds are the following:
"type"
: must be"regular_bg"
for regular backgrounds."height"
: optional field which specifies the height of each regular background in pixels. For example, if the specified height is 256, an image with 1024 pixels of height contains 4 regular backgrounds."palette_item"
: optional field which specifies the name of the bn::bg_palette_item to use for this background. "bpp_mode"
: optional field which specifies the bits per pixel of the regular background. This field is required if an external bn::bg_palette_item is referenced with "palette_item"
:"bpp_8"
: up to 256 colors."bpp_4_auto"
: up to 16 colors per tile. Butano tries to quantize the image to fit the color palette into the required one. It is not supported if an external bn::bg_palette_item is referenced with "palette_item"
."bpp_4_manual"
: up to 16 colors per tile. Butano expects that the image color palette is already valid for this mode."bpp_4"
:"bpp_4_manual"
alias.
The default is "bpp_4_manual"
for 16 color images and "bpp_8"
for 256 color images.
"colors_count"
: optional field which specifies the background palette size [1..256]."repeated_tiles_reduction"
: optional field which specifies if repeated tiles must be reduced or not (true
by default)."flipped_tiles_reduction"
: optional field which specifies if flipped tiles must be reduced or not (true
by default)."palette_reduction"
: optional field which specifies if repeated 16 color palettes must be reduced or not (true
by default)."big"
: optional boolean field which specifies if maps generated with this item are big or not. If this field is omitted, big maps are generated only if needed."tiles_compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"palette_compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"map_compression"
: optional field which specifies the compression of the map data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"compression"
: optional field which specifies the compression of the tiles, the colors and the map data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_regular_bg_items_image.h
is generated in the build
folder.
You can use this header to create a regular background with only one line of C++ code:
#include "bn_regular_bg_items_image.h" bn::regular_bg_ptr regular_bg = bn::regular_bg_items::image.create_bg(0, 0);
Regular background tiles
An image file can contain up to 1024 regular background tiles.
An example of the *.json
files required for regular background tiles is the following:
{ "type": "regular_bg_tiles", "bpp_mode": "bpp_8" }
The fields for regular background tiles are the following:
"type"
: must be"regular_bg_tiles"
for regular background tiles."bpp_mode"
: specifies the bits per pixel of the regular background tiles:"bpp_8"
: up to 256 colors."bpp_4"
: up to 16 colors per tile. Butano expects that the image color palette is already valid for this mode.
"compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"generate_palette"
: optional field which specifies if a background palette must be generated (false
by default)."palette_colors_count"
: optional field which specifies the background palette size [1..256]."palette_compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_regular_bg_tiles_items_image.h
is generated in the build
folder.
You can use this header to create regular background tiles with only one line of C++ code:
#include "bn_regular_bg_tiles_items_image.h" bn::regular_bg_tiles_ptr regular_bg_tiles = bn::regular_bg_tiles_items::image.create_tiles();
Affine backgrounds
An image file can contain multiple affine backgrounds. The size of a small affine background (which are faster) must be 128x128, 256x256, 512x512 or 1024x1024 pixels. Big affine backgrounds are slower CPU wise, but can have any width or height multiple of 256 pixels.
Multiple affine background images are allowed by layering them down on the vertical axis:
An example of the *.json
files required for affine backgrounds is the following:
{ "type": "affine_bg" }
The fields for affine backgrounds are the following:
"type"
: must be"affine_bg"
for affine backgrounds."height"
: optional field which specifies the height of each affine background in pixels. For example, if the specified height is 256, an image with 1024 pixels of height contains 4 affine backgrounds."palette_item"
: optional field which specifies the name of the bn::bg_palette_item to use for this background. "colors_count"
: optional field which specifies the background palette size [1..256]."repeated_tiles_reduction"
: optional field which specifies if repeated tiles must be reduced or not (true
by default)."big"
: optional boolean field which specifies if maps generated with this item are big or not. If this field is omitted, big maps are generated only if needed."tiles_compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"palette_compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"map_compression"
: optional field which specifies the compression of the map data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"compression"
: optional field which specifies the compression of the tiles, the colors and the map data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_affine_bg_items_image.h
is generated in the build
folder.
You can use this header to create an affine background with only one line of C++ code:
#include "bn_affine_bg_items_image.h" bn::affine_bg_ptr affine_bg = bn::affine_bg_items::image.create_bg(0, 0);
Affine background tiles
An image file can contain up to 256 affine background tiles.
An example of the *.json
files required for affine background tiles is the following:
{ "type": "affine_bg_tiles" }
The fields for affine background tiles are the following:
"type"
: must be"affine_bg_tiles"
for affine background tiles."compression"
: optional field which specifies the compression of the tiles data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
"generate_palette"
: optional field which specifies if a background palette must be generated (false
by default)."palette_colors_count"
: optional field which specifies the background palette size [1..256]."palette_compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_affine_bg_tiles_items_image.h
is generated in the build
folder.
You can use this header to create affine background tiles with only one line of C++ code:
#include "bn_affine_bg_tiles_items_image.h" bn::affine_bg_tiles_ptr affine_bg_tiles = bn::affine_bg_tiles_items::image.create_tiles();
Background palettes
An example of the *.json
files required for background palettes is the following:
{ "type": "bg_palette", "bpp_mode": "bpp_8" }
The fields for background palettes are the following:
"type"
: must be"bg_palette"
for background palettes."bpp_mode"
: specifies the bits per pixel of the background palette:"bpp_8"
: up to 256 colors."bpp_4"
: up to 16 colors per tile.
"colors_count"
: optional field which specifies the background palette size [1..256]."compression"
: optional field which specifies the compression of the colors data:"none"
: uncompressed data (this is the default option)."lz77"
: LZ77 compressed data."run_length"
: run-length compressed data."huffman"
: Huffman compressed data."auto"
: uses the option which gives the smallest data size."auto_no_huffman"
: uses the option which gives the smallest data size, excluding "huffman".
If the conversion process has finished successfully, a bn::build
folder.
For example, from two files named image.bmp
and image.json
, a header file named bn_bg_palette_items_image.h
is generated in the build
folder.
You can use this header to create a background palette with only one line of C++ code:
#include "bn_bg_palette_items_image.h" bn::bg_palette_ptr bg_palette = bn::bg_palette_items::image.create_palette();
Audio
By default audio files played with Direct Sound channels go into the audio
folder of your project, and music files played with DMG channels go into the dmg_audio
folder.
Direct Sound stuff is managed by the awesome Maxmod, so if you have an issue with Direct Sound music or with sound effects, well, you know.
DMG channels are handled by the also impressive GBT Player and VGM player, so if you have issues with DMG music, you know where to go.
A really nice application for editing audio files before importing them into your game is OpenMPT.
Direct Sound music
The required format for Direct Sound music is module files with *.mod
, *.xm
, *.s3m
and *.it
extensions.
By default Butano supports up to 16 music channels, but this limit can be increased by overloading the definition of BN_
However, if it is possible don't do this, don't make the poor GBA suffer.
If the conversion process has finished successfully, a bunch of bn::bn::music_items
namespace should have been generated in the build
folder for all music files. You can use these items to play music with only one line of C++ code:
#include "bn_music_items.h" bn::music_items::song.play();
DMG music
The required format for DMG music is module files with *.mod
, *.s3m
and *.vgm
extensions.
The recommended way to generate *.vgm
compatible files is to use hUGETracker 1.01 with timer based tempo disabled:
If the conversion process has finished successfully, a bn::build
folder.
For example, from a file named module.mod
, a header file named bn_dmg_music_items_module.h
is generated in the build
folder.
You can use this header to play the module file with only one line of C++ code:
#include "bn_dmg_music_items_module.h" bn::dmg_music_items::module.play();
You can accompany DMG music module files with a *.json
file with the same name to specify import options.
An example of the *.json
files for DMG music module files is the following:
{ "import_instruments": false, "mod_speed_conversion": true }
Available fields are the following:
"import_instruments"
: optional field which specifies if channel 3 instruments must be imported when importing*.s3m
module files, replacing the default instruments of GBT Player (false
by default). This option is ignored when importing audio files with*.mod
and*.vgm
extensions."mod_speed_conversion"
: optional field which specifies if module files with*.mod
extension speed must be converted from 50Hz to 60Hz (true
by default). This option is ignored when importing audio files with*.s3m
and*.vgm
extensions.
The default DMG music master volume is set to 25% ( bn::
Sound effects
The required format for sound effects is waveform audio files (files with *.wav
extension) without compression or anything weird. Besides, I think stereo files are not allowed.
The recommended quality for sound effects is 8-bits 22050 Hz.
If the conversion process has finished successfully, a bunch of bn::bn::sound_items
namespace should have been generated in the build
folder for all sound files. You can use these items to play sound effects with only one line of C++ code:
#include "bn_sound_items.h" bn::sound_items::sfx.play();