Skip to main content

include_background_gfx

Macro include_background_gfx 

Source
include_background_gfx!() { /* proc-macro */ }
Expand description

Include background tiles from a png, bmp or aseprite file.

This macro is used to convert a png, bmp or aseprite file into a format usable by the Game Boy Advance.

Suppose you have a file in examples/gfx/beach-background.aseprite which contains some tiles you’d like to use.

You import them using:

agb::include_background_gfx!(
    mod backgrounds,
    BEACH => "examples/gfx/beach-background.aseprite"
);

This will generate something along the lines of the following:

// module name comes from the first argument, name of the constant from the arrow
mod backgrounds {
    pub static BEACH: TileData = /* ... */;
    pub static PALETTES: Palette16[] = /* ... */;
}

And BEACH will be an instance of TileData

You can import multiple files at once, and the palette data will be combined so they can all be visible.

agb::include_background_gfx!(
    mod backgrounds,
    BEACH => "examples/gfx/beach-background.aseprite",
    HUD => "examples/gfx/hud.aseprite",
);

§Palettes

The Game Boy Advance, in 16-colour mode can have at most 16 palettes each of size 16. Each tile can only refer to a single one of those palettes. include_background_gfx! will try its best to arrange the colours in the palettes such that the passed background file can be displayed.

However, this isn’t always possible if your background has too many colours in one tile, or too many varieties of palettes between the individual tiles. If this happens, then the call to include_background_gfx! will fail at compile time. You can fix this by either importing as 256 colours, or by changing your backgrounds to use fewer colour variations.

§Transparent backgrounds

The GBA supports a single transparent colour. Any pixels marked with full alpha transparency in the background will be mapped to the first colour of the relevant palette, which is displayed as transparent.

However, that transparency colour will be the one shown behind any background so any space which has no tiles, or you can see all the way through will be shown using that colour.

You can configure which colour that will be with the optional second argument to include_background_gfx!

agb::include_background_gfx!(
    mod backgrounds,
    "00bdfe", // the sky colour hex code
    BEACH => "examples/gfx/beach-background.aseprite",
    HUD => "examples/gfx/hud.aseprite",
);

§Deduplication

If your background has a large number of repeated 8x8 tiles (like the beach background above), then you can let the tile importing do the hard bit of deduplicating those tiles and with that you’ll save some video RAM, which will then allow you to use even more tiles.

Note that once you’ve used deduplication, you need to use the TileData::settings field in order to be able to actually display your given tiles. This is because the tiles could be flipped horizontally or vertically (or both) and combined with other tiles.

agb::include_background_gfx!(
    mod backgrounds,
    BEACH => deduplicate "examples/gfx/beach-background.aseprite",
);

§256 colours

The Game Boy Advance supports both 16-colour and 256-colour tiles. If you’re using 256 colours in some (or all of) your backgrounds, you’ll have to include them in 256 colour mode. You are required to use 256 colour backgrounds with affine tiles.

agb::include_background_gfx!(
    mod backgrounds,
    BEACH => 256 "examples/gfx/beach-background.aseprite",
    HUD => "examples/gfx/hud.aseprite", // you can still import 16-colour backgrounds at the same time
);

§Module visibility

The resulting module that’s being exported can have a different visibility if you want it to. So for instance you could make the resulting module pub or pub(crate) as follows:

agb::include_background_gfx!(
    pub mod backgrounds,
    BEACH => "examples/gfx/beach-background.aseprite",
);

agb::include_background_gfx!(
    pub(crate) mod backgrounds2,
    BEACH => "examples/gfx/beach-background.aseprite",
);

§$OUT_DIR

You may be generating the backgrounds as part of your build.rs file. If you’re doing that, you’ll want to put the generated files in $OUT_DIR. You can refer to this as part of the file name:

include_background_gfx!(mod generated_background, "000000", DATA => "$OUT_DIR/generated_background.aseprite");

§Examples

§fill_with and displaying a full screen background

This example uses RegularBackground::fill_with to fill the screen with a screen-sized image.

use agb::{
    display::{
        tiled::{RegularBackgroundSize, TileFormat, TileSet, TileSetting, RegularBackground},
        Priority,
    },
    include_background_gfx,
};

agb::include_background_gfx!(
    pub mod backgrounds,
    BEACH => "examples/gfx/beach-background.aseprite",
);

let mut gfx = gba.graphics.get();
gfx.set_background_palettes(backgrounds::PALETTES);

let mut bg = RegularBackground::new(
    Priority::P0,
    RegularBackgroundSize::Background32x32,
    TileFormat::FourBpp,
);
bg.fill_with(&backgrounds::BEACH);

§Combining modifiers

Modifiers can be combined, so you can import and deduplicate a 256 colour background.

agb::include_background_gfx!(
    mod backgrounds,
    BEACH => 256 deduplicate "examples/gfx/beach-background.aseprite",
    HUD => deduplicate "examples/gfx/hud.aseprite", // you can still import 16-colour backgrounds at the same time
);