2.15.1
Background layers

Introduction

Background layers are used to implement the levels where gameplay takes place. They can be moved around and always fill the screen. They can be just decorations, or contain actual level structure where sprites can interact and collide (platforms, walls, environmental hazards... )

Background layers can have transparent, cut-through areas where the underlying layer(s) or background color is seen.

Layers are referenced by an index, starting at 0 for the topmost, increasing up to number of layers minus 1 for the bottom-most. The total number of layers is pre-allocated when the engine is initialized with TLN_Init and cannot be changed later at runtime.

Types of layers

Tilengine supports three types of layers:

  • Tiled layer: uses a tilemap and a tile-based tileset
  • Object list: uses an object list and a bitmap-based tileset
  • Single bitmap: uses a whole bitmap

Tiled layers

Tiled layers are composed of tilemaps, a rectangular, grid-like arrangement of square pieces called tiles. These tiles are located inside a tileset, a collection of related square pieces that are assembled to form a level.

Tiled layer graph
Block diagram of a tiled layer

Tiled layers are loaded from .tmx files with the TLN_LoadTilemap function, that gets a filename and an optional layer name, and returns a TLN_Tilemap handler.

TLN_Tilemap tilemap = TLN_LoadTilemap("level.tmx", "foreground");

If layer name is set to NULL, it loads the first layer it encounters:

TLN_Tilemap tilemap = TLN_LoadTilemap("level.tmx", NULL);

Once a tilemap is loaded, it must be assigned to a layer with TLN_SetLayerTilemap function. It takes the layer index and the tilemap handler:

TLN_SetLayerTilemap(0, tilemap);

A tilemap
A tilemap in Tiled editor

Bitmap layers

Bitmap layers use a single, big bitmap image that can be loaded with TLN_LoadBitmap function that just takes a filename (.bmp and .png files supported):

TLN_Bitmap bitmap = TLN_LoadBitmap("background.png)

Once a bitmap is loaded, it must be assigned to a layer with TLN_SetLayerBitmap function. It takes the layer index and the bitmap:

TLN_SetLayerBitmap(0, bitmap);

Bitmap layer graph
Block diagram of a bitmap layer

Object layers

Object layers have a list of different items freely scattered across the playfield. Each item is a bitmap inside a bitmap-based tileset.

Object layer graph
Block diagram of an object layer

Object list are loaded from .tmx files too, with the TLN_LoadObjectList function that takes a filename and an optional layer name, and returns a TLN_ObjectList handle. Just like tiled layers, if no layer name is specified, it loads the first object layer inside the .tmx file:

TLN_ObjectList list = TLN_LoadObjectList("level`.tmx`", NULL);

To enable a object list layer, it must be set with the TLN_SetLayerObjects, that takes the layer index, the object list, and an optional tileset. If no tileset is specified, it uses the default tileset of the object list:

TLN_SetLayerObject(0, list, NULL);

However an explicit bitmap-based tileset can be loaded and assigned:

TLN_Tileset tileset = TLN_LoadTileset("objects.tsx")
TLN_SetLayerObject(0, list, objects);

Common operations

Layers have a common set of operations that are available to all three types of layers

Movement & scroll

Layers can be much bigger than the display area. To set the what zone is being displayed, use TLN_SetLayerPosition passing the layer index, and the horizontal (x) and vertical (y) displacement from the origin located in the top-left corner.

Sets layer 0 starting at x=320 and y=160:

Layer moved to 120,16

Setting the palette

When a layer is configured, it automatically gets the palette of the attached asset -tileset or bitmap-. However is possible to change the palette to another one with TLN_SetLayerPalette, passing the layer index and a handle to a TLN_Palette object.

TLN_Palette palette = TLN_LoadPalette("palette.act");
TLN_SetLayerPalette(0, palette);

Blending

Blending allows to combine the color of a layer with the underlying color already present. There are several predefined blending modes, read chapter.

To enable blending on a layer use TLN_SetLayerBlendMode passing the layer index and one of available TLN_Blend modes:

To disable blending, use BLEND_NONE mode:

Priority

By default, background layers are drawn behind the sprites -that's why they're background layers-. However a given layer can also be drawn in front of sprites, giving it priority over sprites. Use TLN_SetLayerPriority passing the layer index, and a boolean with trueto enable or false to or disable priority:

/* enable priority on layer 0 */
/* disable priority on layer 0 */

Clipping rectangle

Each layer can be assigned a clipping rectangle: a region that delimits where drawing occurs inside the window, leaving outside pixels unaffected. By default the clipping rectangle is disabled and the layer covers the entire window.

To enable the clipping rectangle, call TLN_SetLayerClip passing the index of the layer, and four numbers telling the x,y of the top-left corner, and the x,y of the bottom-right corner. For example, to set clipping in layer 0 from 32,20 to 360,240:

TLN_SetLayerClip (0, 32,20, 360,240);

Clipping rectangle 32,20 - 360,240:

Clipping rectangle

To disable the clipping rectangle, call TLN_DisableLayerClip passing the layer index to disable:

Disabling

Layers can be disabled when they're not needed anymore with TLN_DisableLayer, passing the layer index.

Enabling

A disabled layer with TLN_DisableLayer can be re-enabled again, as long as it was previously configured and contains valid data. To enable a layer use TLN_EnableLayer passing the index to the layer to enable:

Special effects

Column offset

This feature allows displacing vertically each column of tiles in screen space by a given amount of pixels. This can be used to fake vertical parallaxing, or to do moderate tilting and deformation of terrain.

To setup the effect, it needs an array of integers as large as the number of columns that fit in one screen plus 2. For example, with a 400x240 framebuffer and are 16x16 tiles, the number of positions is 400/16 + 2 = 27. Call TLN_SetLayerColumnOffset passing the layer index and a pointer to the array of integers:

const int hres = 400;
const int tile_width = 16;
const int size = hres/tile_width + 2;
int offsets[size] = { 0 };
/* ... */

Now the layer 0 column offset is linked to the offsets array. Setting any value(s) inside the array and drawing a frame has immediate visible effects, there's no need to call the function each time. For example, to create a slightly sloped terrain:

int c;
for (c = 0; c < size; c += 1)
offsets[c] = c;

Column offset: each column is displaced 1 pixel incrementally:

Column offset

To disable the effect, call the function with a NULL pointer instead of a valid array:

This effect is only available on tiled layers.

Scaling

Layers can be drawn upscaled or downscaled with an arbitrary factor. The scaling starts in screen space at the top-left corner, so the scrolling position isn't affected by scaling. To enable scaling, call TLN_SetLayerScaling passing the layer index and two floating point values with the horizontal and vertical factor, respectively. Values greater than 1.0 upscale, and smaller than 1.0 downscale. For example to set an horizontal downscaling of 0.5 and vertical upscaling of 1.5 for layer 0:

TLN_SetLayerScaling (0, 0.5f, 1.5f);

Layer scaling x0.5 horizontal, x1.5 vertical:

Column offset

To disable scaling, call TLN_ResetLayerMode passing the layer index:

This effect is available for tiled and bitmap layers.

Affine transform

Affine transform allows to rotate, translate and scale any layer (much like SNES Mode 7). To enable this transformation, call TLN_SetLayerTransform passing the layer index, rotation angle in degrees, two floating point values with the center of rotation in screen space, and two floating point values with horizontal and vertical scaling. For example, to enable affine transform on layer 0, 30 degrees rotation around the center of the screen, and 1.5 upscaling in both axis:

TLN_SetLayerTransform (0, 30.0f, 240.0f,160.0f, 1.5f,1.5f);

30ยบ degree rotation around 240,160 (screen center), x1.5 upscaling:

Affine transform

TIP: affine transform is an intensive operation. If you just want to implement scaling but not rotation, use TLN_SetLayerScaling instead because it's much more lightweight.

To disable affine transform, call TLN_ResetLayerMode passing the layer index:

This effect is available for tiled and bitmap layers.

Per-pixel mapping

Per-pixel mapping is a similar operation to column offset, but applied to every screen pixel instead of just every column.

To setup the effect, it needs an array of TLN_PixelMap items with as many positions as pixels in the framebuffer. For example, for a 480x320 setup, it needs to have 480x320 = 153,600 items. Each item contains a pair of integer values with the coordinates of that pixel relative to the to left corner of the screen at 0,0. Call TLN_SetLayerPixelMapping passing the layer index and a pointer to the array of TLN_PixelMap items:

const int hres = 480;
const int vres = 320;
const int num_pixels = hres * vres;
TLN_PixelMap pixel_map[num_pixels];
/* ... */
TLN_SetLayerPixelMapping (0, pixel_map);

Pixel mapping applying some trigonometric displacements to the TLN_PixelMap array:

Affine transform

Let's we want that pixel at 320,240 takes its value from pixel located at 200,100. First we have to calculate which pixel to modify inside the TLN_PixelMap array. The formula is:

index = y * width + x

Then we set dx and dy with the coordinates of the desired source pixel:

int x = 320; /* pixel we want to remap */
int y = 240;
int index = y * width + x;
/* ... */
pixel_map[index].dx = 200;
pixel_map[index].dy = 100;

This effect is available for tiled and bitmap layers.

Mosaic

The mosaic effect pixelates the layer, making some pixels bigger and skipping others so the relative image size keeps constant. It's similar to the mosaic effect in SNES, but more flexible. Different horizontal and vertical pixel values are possible -not just square pixels-, and any size can be set, not just powers of 2. To enable the effect, call TLN_SetLayerMosaic passing the layer index, the horizontal pixel size, and the vertical pixel size. For example to set mosaic on layer 0 with 8 pixel horizontal factor and 6 pixel vertical factor:

Mosaic effect with 8 horizontal and 6 vertical pixel size factor:

Affine transform

To disable the mosaic effect, just call TLN_DisableLayerMosaic passing the layer index:

This effect is available for tiled and bitmap layers.

Special effects chart

Not all special effects are available for any layer. This chart shows which effects are available on which layers:

Effect Tiled Bitmap Object
Column offset yes - -
Scaling yes yes -
Affine yes yes -
Per-pixel map yes yes -
Mosaic yes yes -

Gameplay support

Retrieving active assets

Sometimes there's needed to get what assets are used by a given layer, especially when the layers have been automatically populated with TLN_LoadWorld

Query Returns
TLN_GetLayerType Returns layer type, TLN_LayerType enumeration
TLN_GetLayerTilemap Returns active tilemap on tiled layers
TLN_GetLayerTileset Returns active tileset on tiled an object layers
TLN_GetLayerBitmap Returns active bitmap on bitmapped layers
TLN_GetLayerPalette Returns active palette if the layer uses one
TLN_GetLayerObjects Returns active object list on object layers

Getting Tile data

Gameplay using layers for character interaction will require gathering information about it:

  • Size in pixels
  • Details about any tile

Use TLN_GetLayerWidth and TLN_GetLayerHeight to get size in pixels:

int width = TLN_GetLayerWidth(0);
int height = TLN_GetLayerHeight(0);

To get details about a specific tile, call TLN_GetLayerTile passing the layer index, the x,y pixel in layer space, and a pointer to a TLN_TileInfo struct that will hold the returned data.

TLN_TileInfo tile_info; /* declare struct to hold returned data */
TLN_GetLayerTile (0, 1800,300, &tile_info); /* get layer 0 tile at 1800,300 */

NOTE: This function is only available for tiled layers

Summary

This is a quick reference of related functions in this chapter:

Function Quick description
TLN_SetLayerTilemap Configures a tiled background layer
TLN_SetLayerBitmap Configures a full-bitmap background layer
TLN_SetLayerObjects Configures an object list background layer
TLN_SetLayerPalette Sets the color palette to the layer
TLN_SetLayerPosition Moves the viewport inside the layer
TLN_SetLayerClip Enables clipping rectangle
TLN_DisableLayerClip Disables clipping rectangle
TLN_SetLayerBlendMode Sets the blending mode (transparency effect)
TLN_SetLayerPriority Sets layer to be drawn on top of sprites
TLN_SetLayerScaling Enables layer scaling
TLN_SetLayerTransform Sets affine transform matrix to enable rotating and scaling
TLN_SetLayerPixelMapping Sets the table for pixel mapping render mode
TLN_ResetLayerMode Disables scaling or affine transform for the layer
TLN_SetLayerColumnOffset Enables column offset mode for this layer
TLN_SetLayerMosaic Enables mosaic effect
TLN_DisableLayerMosaic Disables mosaic effect
TLN_DisableLayer Disables the specified layer so it is not drawn
TLN_GetLayerWidth Returns the layer width in pixels
TLN_GetLayerHeight Returns the layer height in pixels
TLN_GetLayerTile Gets info about the tile located in tilemap space
TLN_EnableLayer
bool TLN_EnableLayer(int nlayer)
Enables a layer previously disabled with TLN_DisableLayer.
Definition: Layer.c:747
BLEND_MIX50
@ BLEND_MIX50
Definition: Tilengine.h:89
TLN_SetLayerPalette
bool TLN_SetLayerPalette(int nlayer, TLN_Palette palette)
Sets the color palette to the layer.
Definition: Layer.c:386
TLN_SetLayerTilemap
bool TLN_SetLayerTilemap(int nlayer, TLN_Tilemap tilemap)
Configures a tiled background layer with the specified tilemap.
Definition: Layer.c:134
TLN_LoadTileset
TLN_Tileset TLN_LoadTileset(const char *filename)
Loads a tileset from a Tiled .tsx file.
Definition: LoadTileset.c:254
TLN_LoadBitmap
TLN_Bitmap TLN_LoadBitmap(const char *filename)
Load image file (8-bit BMP or PNG)
Definition: LoadBitmap.c:204
TLN_SetLayerBitmap
bool TLN_SetLayerBitmap(int nlayer, TLN_Bitmap bitmap)
Configures a background layer with the specified full bitmap.
Definition: Layer.c:156
TLN_SetLayerTransform
bool TLN_SetLayerTransform(int layer, float angle, float dx, float dy, float sx, float sy)
Sets affine transform matrix to enable rotating and scaling of this layer.
Definition: Layer.c:890
TLN_DisableLayer
bool TLN_DisableLayer(int nlayer)
Disables the specified layer so it is not drawn.
Definition: Layer.c:785
TLN_Tilemap
struct Tilemap * TLN_Tilemap
Definition: Tilengine.h:260
TLN_SetLayerClip
bool TLN_SetLayerClip(int nlayer, int x1, int y1, int x2, int y2)
Enables clipping rectangle on selected layer.
Definition: Layer.c:1015
TLN_SetLayerScaling
bool TLN_SetLayerScaling(int nlayer, float xfactor, float yfactor)
Sets simple scaling.
Definition: Layer.c:925
TLN_PixelMap
Definition: Tilengine.h:251
TLN_PixelMap::dx
int16_t dx
Definition: Tilengine.h:252
TLN_DrawFrame
void TLN_DrawFrame(int frame)
Draws a frame to the window.
Definition: Window.c:1011
TLN_GetLayerHeight
int TLN_GetLayerHeight(int nlayer)
Returns the layer height in pixels.
Definition: Layer.c:324
TLN_Tileset
struct Tileset * TLN_Tileset
Definition: Tilengine.h:259
TLN_LoadObjectList
TLN_ObjectList TLN_LoadObjectList(const char *filename, const char *layername)
Loads an object list from a Tiled object layer.
Definition: ObjectList.c:244
TLN_SetLayerPixelMapping
bool TLN_SetLayerPixelMapping(int nlayer, TLN_PixelMap *table)
Sets the table for pixel mapping render mode.
Definition: Layer.c:957
TLN_ObjectList
struct ObjectList * TLN_ObjectList
Definition: Tilengine.h:266
BLEND_NONE
@ BLEND_NONE
Definition: Tilengine.h:87
TLN_LoadPalette
TLN_Palette TLN_LoadPalette(const char *filename)
Loads a palette from a standard .act file.
Definition: LoadPalette.c:47
TLN_Bitmap
struct Bitmap * TLN_Bitmap
Definition: Tilengine.h:265
TLN_DisableLayerMosaic
bool TLN_DisableLayerMosaic(int nlayer)
Disables mosaic effect for selected layer.
Definition: Layer.c:1184
TLN_SetLayerPriority
bool TLN_SetLayerPriority(int nlayer, bool enable)
Sets full layer priority, appearing in front of sprites.
Definition: Layer.c:268
TLN_LoadTilemap
TLN_Tilemap TLN_LoadTilemap(const char *filename, const char *layername)
Loads a tilemap layer from a Tiled .tmx file.
Definition: LoadTilemap.c:171
TLN_Palette
struct Palette * TLN_Palette
Definition: Tilengine.h:261
TLN_SetLayerMosaic
bool TLN_SetLayerMosaic(int nlayer, int width, int height)
Enables mosaic effect (pixelation) for selected layer.
Definition: Layer.c:1157
TLN_SetLayerPosition
bool TLN_SetLayerPosition(int nlayer, int hstart, int vstart)
Sets the position of the tileset that corresponds to the upper left corner.
Definition: Layer.c:547
TLN_TileInfo
Definition: Tilengine.h:196
TLN_GetLayerWidth
int TLN_GetLayerWidth(int nlayer)
Returns the layer width in pixels.
Definition: Layer.c:303
TLN_DisableLayerClip
bool TLN_DisableLayerClip(int nlayer)
Disables clipping rectangle on selected layer.
Definition: Layer.c:1026
TLN_SetLayerColumnOffset
bool TLN_SetLayerColumnOffset(int nlayer, int *offset)
Enables column offset mode for this layer.
Definition: Layer.c:730
TLN_ResetLayerMode
bool TLN_ResetLayerMode(int nlayer)
Disables scaling or affine transform for the layer.
Definition: Layer.c:988
TLN_SetLayerBlendMode
bool TLN_SetLayerBlendMode(int nlayer, TLN_Blend mode, uint8_t factor)
Sets the blending mode (transparency effect)
Definition: Layer.c:352
TLN_GetLayerTile
bool TLN_GetLayerTile(int nlayer, int x, int y, TLN_TileInfo *info)
Gets info about the tile located in tilemap space.
Definition: Layer.c:638
TLN_PixelMap::dy
int16_t dy
Definition: Tilengine.h:253