DEV Community

segfault
segfault

Posted on

Creating a Rendering Engine

First we start with palettes, we want something that supports 1BPP, 2BPP, 3BPP, and 4BPP modes subject to hardware constraints.

A master palette determines what colors are available to the rendering engine. On some hardware, this can be modified by the user at will, whereas it may be fixed on others. Some may even have fixed set of master palettes to choose from (such as CGA).

A master palette is specified by a series of RGB triples corresponding to the mode. it will select a master palette which approximates the input palette by using one with the list Euclidean distance when possible. On systems where the available palettes are fixed, this behavior may be counterintuitive.

For select ispecs, recoloring palettes may be supported.
Recolor palettes are used provided to allow reuse of limited assets. This is a common strategy on consoles to stretch limited graphical assets. The use of recolor palettes works very well with some target systems such as the SNES or the Commander X16. it should support up to 16 recolor palettes at any given time. Recolor palettes work by indexing the master palette,allowing for limited bit depth to be utilized to great effect.

It is customary for recolor palette 0 to reflect the master palette. This is because on some systems (such as the CX16 or the Super NES) it is possible for the entire palette to fit into recolor memory while using the same pixel format. Otherwise, the recolor palette may carry significant overhead with it, for example:

Adapter Depth RP Size Table Size
EGA 4bpp $400 $4000
CGA 2bpp $100 $1000

Better off implementing speed to memory utilization when performing recolor operations. For many games, it is more important that the rendering occurs quickly than it is that memory is conserved.
Games where memory is a pressing concern should disable recolor rendering.

1BPP Mode

1BPP mode represents a monochrome screen. It only consists of two colors: index 0, and index 1. One byte represents a row of 8 pixels in packed mode.

2BPP Mode

2BPP mode represents 4-color indexed mode, such as would be seen in CGA mode 4h or on the NES.

4BPP Mode

4BPP mode represents 16-color index mode, such as would be seen in EGA mode 0Dh or on the SNES.

8BPP Mode

8BPP mode represents 256-color index mode, such as would be see on VGA.

Transparency

1-bit transparency should be supported. Many platforms have native transparency, although many do not. In particular, BSD compatible video hardware does not natively support it. When transparency is enabled, index 0 is treated as the transparent color.

Transparency may be an expensive operation on systems which do not natively support it, but some attempts are made to alleviate it. it may take one or more of the following strategies to implement transparency:

  • Calculating a transparency map for the image.
  • Use of blitter operations to compose the new image.

Images

An image is a combination of raw pixel data, an image format, and its
dimensions. An image's bounds can be expressed using a 16-bit integer; therefore the maximum image size in rendering engine is 65536x65536.

Format

An image format ifmt provides specific guidance respecting how images should be interpreted. It consists of an image specification ispec and an palette set.

An ispec provides generic information about the display surface, including its bit depth, the number of planes it has (up to 16), and several bits controlling its behavior.

Bitplane:The memory is arranged in such a way that a single byte refers to a bitplane for the memory. This behavior is used in EGA's mode 0Dh, where one byte represents 8 pixels in each plane.

Reversed:The memory is arranged in such a way that the first pixel is associated with the most-significant bit of the word rather than the least-significant bit. The opposite mode is in-order.

Interlaced:The memory is arranged in such a way odd rows precede
even rows.The opposite mode is progressive scan.

Recolor:This ispec supports palette recoloring. If this bit is not set, recolor palettes will not be applied.

An ispec which has 1 plane and either does not set the bitplane flag or has a bit depth of 1BPP is called a packed ispec. Packed ispecs relatively easy to manipulate but may not be internally supported by the external interface should use a format where all of these
options are disabled (i.e., a packed, progressive-scan, in-order bitmap)when possible, preferring to convert them to their optimal format on the fly. This format is usually easy to edit in situ, and many platforms present their graphics in this format, but there may be cases where this cannot be done.

Interchange

Images are usually large objects and are not easy to manipulate by hand.Because of this, it support several formats for interchange of both raster and tile images. The following formats will be supported for raster bitmaps:

  • Bitmap Format
  • PCX, a commonly used interchange format in the early days of the PC.
  • BMP, in indexed mode only and supporting either raw or RLE compression.

In most cases, it is preferable to use the bitmap format as it is optimized for most PC. The PCX format is included because it is capable of easily encapsulating screen dumps on older compatibles, whereas BMP is more or less accessible in most modern operating environments. In some cases,this may not be enough, so a generic interface is provided to work with additional formats.

For tile pattern data, only the bitmap format is supported directly;
however,the gfx tool is provided to perform basic tilesheet manipulation.Because there are not many containers suitable for this sort of application, this is deemed sufficient. As with bitmaps, however, the interface will permit you to write your own I/O routines for handling novel formats should the need arise.

Engine Modes

There are several rendering engine modes to accommodate the various
graphical needs of the renderer. The rendering modes attempt to make the most of the platform they are on. VERA has fixed graphical capabilities and is the easiest to express because of that. There are 3 modes currently available, all of which with layers. Mode 0 provides two tile-maps, Mode 1 provides 2 bitmaps, and Mode 2 provides a mixture of either bitmaps or tile-maps.

Some of these modes could be consolidated in principle; in practice, not all modes are supported, and it is important to know which modes are capable of being performed.

Mode 0: Tile-map Mode, 320x200

Mode 0 consists of up to two tile-map layers, with each layer being able to either 8x8 or 16x16 tiles. Layer 0 is always on;
layer 1 can be selectively disabled and has transparency when enabled. On some platforms, the two layers cannot be composed; if this is the case, then when layer 1 is enabled, the layer 0 tiles will not be enabled.

Tiles are represented graphically using "patterns". A pattern is a
graphical asset which represents the tile, but may be flipped in either direction. Color depth may occur at 1BPP, 2BPP, 4BPP, or 8BPP subject to the rendering capabilities of the platform. The memory requirements for a complete pattern table are as follows:

BPP 8x8, single 8x8, table 16x16, single 16x16, table
1 $8 $2000 $20 $8000
2 $10 $4000 $40 $10000
4 $20 $8000 $80 $20000
8 $40 $10000 $20 $40000

Because of this, not all available patterns may fit in memory. The pattern table is thus divided into "banks" of 16 patterns each. It may be necessary to bank patterns in and out according to need; as an appropriate algorithm for doing so often application-dependent, no algorithm for doing so is provided here. With that being said, a pattern reference (or tile) fits comfortably into two bytes:

typedef struct {
    uint16_t pattern:10; /* Note: MSB should be set */
    uint16_t palette:4; /* Palette index */
    uint16_t hmirror:1; /* Horizontal Mirror */
    uint16_t vmirror:1; /* Vertical Mirror */
}tile_t;
Enter fullscreen mode Exit fullscreen mode

Tile-maps have a minimum size of 32x32 and may be as large as 256x256.Thus,a tile map ranges from anywhere between 2KB and 128KB, with minimum number of pixels covered by the map being 64K and the maximum being 16M. Tile-maps are scroll-able by a 12-bit scroll index, with the first byte representing the origin tile and the third nybble representing the fine scroll. Tile-maps may be rectangular; for instance, a 64x32 map may be used for complete coverage of a screen with 8x8 tiles. The following memory requirements for a single tile-map are given below:

x32 x64 x128 x256
32 2KB 4KB 8KB 16KB
64 4KB 8KB 16KB 32KB
128 8KB 16KB 32KB 64KB
256 16KB 32KB 64KB 128KB

Note that some platforms either do not support 8x8 patterns, or they support it in a way that would lead to attribute clash. In this case, the pattern table should consist of 16x16 tiles. Because the pattern tables are arranged in banks, a pattern table must be allocated multiples of 16.There may be a minimum pattern table size on some platforms.

Mode 1: Bitmap Mode, 320x200

Bitmap Mode allocates the screen memory entirely for the purpose of
rendering bitmaps.This can be used for full-screen pixel-addressable
graphics,and still supports sprites. Up to two bitmap layers can used
subject to hardware limitations. Layer 1 is always transparent, but may be disabled. Some platforms provide enough RAM for double buffering to occur. If it the capability exists, this will be done by default. Double buffering can improve performance on systems where it is supported. When possible,the fastest method of rendering the bitmap will also be performed.

Each layer allocates at least enough space for a 320x200 bitmap. When
selecting the bit depth for this mode, you should select a depth which balances complexity with available memory.The following minimum memory requirements must be met for each color depth:

Depth 1 Layer 2 Layers
1BPP : $1F40 $3E80
2BPP : $3E80 $7D00
4BPP : $7D00 $FA00
8BPP : $FA00 $1:F400

Note that when double buffering is requested (as it is by default), these sizes may double. In some cases, Bitmap mode may be simulated; for instance, there is no 320x200 1BPP mode on CGA, and this must be simulated using pixel doubling for it's 640x200 mode 6. For platforms which only support pattern rendering, a lookup table may be used to render such a bitmap.Clipping regions are supported with respect to each layer.Clipping allows for writes to the layer to be restricted to a certain region and is specified using a bounding rectangle. Writes outside of the clipping region will be ignored.

Mode 3: Mixed Mode, 320x200

Mixed mode is a combination of modes 0 and 1. Either layer may specified as a tile-map or a bitmap,

Sprites

Some platforms support hardware sprites, whereas others may be able to simulate them. Sprites may occupy any space on the screen and may even travel off-screen. A may be recolored if recoloring is supported. Sprites may be 8, 16, 32, or 64 pixels wide. A sprite which is not on-screen is not rendered. The following structure encapsulates a sprite.

typedef struct {
    uint8_t xCoarse;
    uint8_t yCoarse;
    uint8_t xFine:4;
    uint8_t yFine:4;
    uint8_t palette:4;
    uint8_t size:2;
    uint8_t hmirror:1;
    uint8_t vmirror:1;
    void* data;
}sprite_t;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)