Home

Awesome

GESTE

GEneric Sprite and Tile Engine

Alire Build Status codecov

GESTE is a sprite and tile 2D render engine designed to run on micro-controllers low performance systems. GESTE also provides a basic math and physic engine using fixed point arithmetic.

<a href="https://youtu.be/793ocsfss9g"> <img src="doc/resources/rpg_numworks_YT.JPG" width="300"> </a>

Creating maps

GESTE is developed in parallel with tiled-code-gen, a tool that generates code from the Tiled Map Editor.

Examples

In this repository you can find three examples of games using GESTE. All the examples are made with Tiled map editor and tiled-code-gen.

Here is the list of examples:

You can build and try the examples using GNAT Community (only tested on Linux so far).

Design

Layers

In GESTE, a scene is made of layers. Native layers can be Sprite, Grid or Text. You can implement you own type of layers if you want to.

Layers have a priority which tells in which order they will be drawn on the screen.

Rendering

The rendering algorithm is somewhat similar to ray casting. Instead of taking each objects of the scene and drawing it on the screen, the engine takes each pixel and tries to find its color from the different objects of the scene.

For each pixel of the area that is being drawn, GESTE will go through the list of layers and see if the corresponding pixel inside the layer is transparent or not. When a non transparent pixel is found, the pixel is pushed to the screen and the procedure starts again for the next pixel. If all the layers have a transparent pixel, the background color is used.

The more layers to go through, the more time time it will take to render a pixel.

Rendering API

There are three rendering functions in GESTE.

Render_Window

Render_Window renders all the pixels of a given rectangle window. See above for the rendering algorithm.

Render_Dirty

Render_Dirty only renders the pixels that changed since the last render.

Depending on the performance of CPU, the time it takes to update pixels on the screen or the complexity of the scene, it can take too much time to render the full screen for every frame.

For those reasons, GESTE is capable of rendering only the objects that changed since the previous frame. And for those objects, it will try to update the smallest area possible.

Right now the engine will simply find the rectangle that fits the old and new position, and update that rectangle by calling the Render_Window function. Of course this works best if the new position is not too far from the old one, otherwise the update rectangle will be large.

The layers that changed are called dirty. There are several reasons for a layer to be dirty, changing position, changing tile of a sprite layer, changing text of a text layer.

Render_All

Render_All finds the smallest rectangle that contains all the layers and calls Render_Window.

Backend (Pushing pixels to the screen)

The rendering functions do not draw directly on the screen, they push pixels into an array (provided by the caller) and then call a function (provided by the caller) to send that array of pixel to the screen.

The caller also has to provide a function to set the drawing area,

This mechanism combined with selective rendering (Render_Dirty) can be necessary when the screen is connected via SPI or I2C because it can cost too much to send the entire screen at one, and also when there's not enough RAM to hold a frame buffer for the entire screen.

If the rendering is done directly into a frame buffer in RAM, then it is possible to directly use the frame buffer as pixel buffer for the rendering functions. In that case, the drawing area will be the entire screen frame buffer.

You will find examples of backends in this repository.