SCI/FreeSCI/Graphics/Standard data types

From ScummVM :: Wiki
< SCI‎ | FreeSCI‎ | Graphics
Revision as of 16:06, 20 January 2009 by Timofonic (talk | contribs) (Merging of the FreeSCI documentation. Page done.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Standard data types

There are a number of standard data types defined in src/include/gfx_system.h which are used all over the place in the graphics subsystem; therefore, they warrant some special attention in order to understand how it works.

point_t
This data type is nothing more than a tuple (x,y). It describes a coordinate on the screen; a one-line way to generate a point_t is to use the function gfx_point(x,y).

rect_t

This type describes a rectangular area on the screen, as a four-tuple (x,y,xlen, ylen), where the point (x, y) describes the upper left point of the rectangle, whereas xlen and ylen are the number of pixels the rectangle extends to the right on the x and downwards on the y axis, respectively. A rect_t can be generated in-line by the function gfx_rect(x,y,xl,yl).

A number of functions are available to operate on rect_ts. These functions are 'pure' in the functional sense, meaning that they do not modify the original rectangle, but, rather, return a new one (of course, an optimizing compiler will make this a moot point from a performance perspective).

gfx_rect_equals(rect_a, rect_b)
This function is a predicate that returns non-zero if rect_a describes the same rectangle as rect_b.
gfx_rect_translate(rect, point)
Returns a rectangle which equals rect translated (moved) by the (x, y) tuple described by the point parameter (i.e. point is interpreted as a relative coordinate).
gfx_rect_subset(rect_a, rect_b)
A predicate to determine whether all pixels contained in the area described by rect_a are also contained in the area described by rect_b. Reflexive and transitive.
gfx_rects_overlap(rect_a, rect_b)
A predicate to test whether there exists a pixel in the area described by rect_a which is contained in the area described by rect_b. Reflexive and symmetric.
gfx_rects_merge(rect_a, rect_b)
Returns the smallest rectangle containing both rect_a and rect_b.

gfx_pixmap_color_t

This structure describes a single color in a pixmap. It consists of 8 bit r, g, b values to describe a color; when used in a pixmap, it is part of a palette of gfx_pixmap_color_ts where the entry at index i describes the color of the respective color index i inside the pixmap.

In palette mode, the global_index entry is used to store the color index entry of the global palette that correlates with the pixmap index (or GFX_COLOR_INDEX_UNMAPPED if this value has not been determined yet).

gfx_color_t

gfx_color_t structures contain color information for all three color maps. They consist of a gfx_pixmap_color_t structure, visual, which describes the effects of the color on the visual map, an alpha entry to describe the color's transparency (0 means 'opaque', 255 means 'totally transparent', although graphics drivers may choose to slighly alter those meanings for performance considerations), priority and control values for the respective maps, and a mask to determine the maps affected.

This mask is a bitwise-OR of the constants GFX_MASK_VISUAL (meaning "draw to the visual map"), GFX_MASK_PRIORITY ("draw to the priority map") and GFX_MASK_CONTROL (guess).

gfx_mode_t

The FreeSCI graphics subsystem only supports a small subset of all possible graphics modes; specifically, it only supports modes where the integer value of each pixel can be stored in 8, 16, 24, or 32 bits. Color index mode is supported, but non-indexed mode has additional requirements: Each color aspect of red, green, and blue must be represented by a consecutive sub-vector <vc, vc</sub+1, ... ,vc+n-1> of the total color vector <v0, v1, ... ,vb-1>, where n and c are non-negative integers, and c+n ≤ b holds. With vb being the most significant bit of the total bit vector, we also require that for each m where 0 < m < n the bit vc+m should, if set, increase brightness about twice as much as setting vc+m-1 would. This allows us to represent each color aspect by means of an AND bitmask and an integer shift value.

This, along with a global palette and the scaling factors, is the core of the gfx_mode_t data. It also contains a shift values and an AND bitmask for alpha values; if these values are set to non-zero by the graphics driver, alpha channel information will be written to the same block of data the color values are written to when pixmaps are calculated. If they are not set, a separate 8bpp alpha data block will be added to the pixmaps.

gfx_pixmap_t

The gfx_pixmap_t structure is another fundamental element of the graphics subsystem. It describes a single pixmap, such as a background picture, a cel, a mouse pointer, or a single line of text. It contains up to two references to the graphical data it describes: One unscaled block of color-indexed data (index_data, and another block scaled and in the graphics driver's native format (data).

Each pixmap contains a local palette of colors_nr gfx_pixmap_color_t entries, called colors. This palette is allocated dynamically and may be NULL if no index_data block is present.

Also, a tuple (xoffset, yoffset) describes the pixmap's 'hot spot'. This is a relative offset into the unscaled data; it is used to describe the point which drawing operations will refer to. This means that pixmap draw operations on this pixmap will cause it to be drawn xoffset pixels (unscaled) to the left of the coordinate specified.

Next comes the unscaled pixmap data, called index_data, which occupies a size of index_xl * index_yl bytes. Each byte is either a reference into the palette, or GFX_COLOR_INDEX_TRANSPARENT (0xff), which means that it describes a transparent pixel, unless 256 colors are indeed present in the palettete[1].

The pointer data, unless NULL, points to a block of data allocated to contain the translated graphical data in the graphics driver's native format. The number of bytes per pixel equals the bytespp property of the gfx_mode_t structure it was allocated for, whereas its horizontal and vertical extensions are stored in the xl and yl properties. Unless the graphics mode indicated that it supports an alpha channel itself, a separate alpha_map is also provided, at 8bpp.

Each pixmap also comes with a pixmap_internal block, which may be used by graphics drivers to store internal information (like pixmap repository handles).

Finally, each pixmap comes with a set of flags with the following meanings:

GFX_PIXMAP_FLAG_SCALED_INDEX
The pixmaps index data is already scaled; any algorithm for calculating data (and, possibly, alpha_map) therefore must not scale it again.
GFX_PIXMAP_FLAG_EXTERNAL_PALETTE
The palette supplied with the pixmap is stored externally, meaning that it must not be freed when the pixmap itself is freed.
GFX_PIXMAP_FLAG_INSTALLED
The pixmap has been installed in the pixmap repository (used by the operational layer, although graphics drivers may choose to verify this if they don't trust that layer.
GFX_PIXMAP_FLAG_PALETTE_ALLOCATED
(only relevant for color index mode) The pixmap's palette colors have been allocated in the internal palette listing and have been set appropriately in the palette
GFX_PIXMAP_FLAG_PALETTE_SET
(only relevant in color index mode) The pixmap's palette colors have been propagated to the graphics driver
GFX_PIXMAP_FLAG_DONT_UNALLOCATE_PALETTE
(only relevant in color index mode) Instructs the pixmap freeing operations not to free the palette colors allocated by the pixmap. This is used in cases where the palette is stored externally.

src/include/gfx_tools.h defines many functions for creating pixmaps, allocating index data blocks, copying pixmap regions etc.

gfx_bitmap_font_t

These structures provide a bitmap lookup table intended for up to 256 entries. In practice, they are used to store font data. There is little surprising about this structure, with the possible exception of the difference between the height and line_height variables: height describes the actual character size, whereas line_height only describes how many pixels the text rendering functions should leave in between text lines.

  1. This may cause a problem for SCI1 support, which explicitly allows for 256 separate colors to be used alongside with transparency. Possible solutions include a separate transparency bitmap or increasing the number of bits per index_data entry to 16bpp.