Layer and color documentation

This commit is contained in:
Wayne Venables
2023-03-04 22:14:33 -08:00
parent 30385af67f
commit 964eff0f0a
7 changed files with 457 additions and 360 deletions

View File

@@ -11,46 +11,51 @@
#define BLACK_MAX MAXX // size of buffer with black color (used to clear rest of unused line)
/// @addtogroup Layers Overlay Layers
/// @{
// VGA PIO program
#define BASE_OFFSET 17 // offset of base layer program
#define LAYER_OFFSET 0 // offset of overlapped layer program
#define BASE_OFFSET 17 ///< Offset of base layer PIO program
#define LAYER_OFFSET 0 ///< Offset of overlapped layer PIO program
// layer program
#define LAYERPROG_BASE 0 // program of base layer (overlapped layers are OFF)
#define LAYERPROG_KEY 1 // layer with key color
#define LAYERPROG_BLACK 2 // layer with black key color
#define LAYERPROG_WHITE 3 // layer with white key color
#define LAYERPROG_MONO 4 // layer with mono pattern or simple color
#define LAYERPROG_RLE 5 // layer with RLE compression
#define LAYERPROG_BASE 0 ///< Program of base layer (overlapped layers are OFF)
#define LAYERPROG_KEY 1 ///< Layer with key color
#define LAYERPROG_BLACK 2 ///< Layer with black key color
#define LAYERPROG_WHITE 3 ///< Layer with white key color
#define LAYERPROG_MONO 4 ///< Layer with mono pattern or simple color
#define LAYERPROG_RLE 5 ///< Layer with RLE compression
#define LAYERPROG_NUM 6 // number of layer programs
#define LAYERPROG_NUM 6 ///< Number of layer programs
// layer mode (CPP = clock cycles per pixel)
// Control buffer: 16 bytes
// Data buffer: 4 bytes
// fast sprites can be up Control buffer: width*2 bytes
// sprites Data buffer: width bytes
#define LAYERMODE_BASE 0 // base layer
#define LAYERMODE_KEY 1 // layer with key color
#define LAYERMODE_BLACK 2 // layer with black key color
#define LAYERMODE_WHITE 3 // layer with white key color
#define LAYERMODE_MONO 4 // layer with mono pattern
#define LAYERMODE_COLOR 5 // layer with simple color
#define LAYERMODE_RLE 6 // layer with RLE compression
#define LAYERMODE_SPRITEKEY 7 // layer with sprites with key color
#define LAYERMODE_SPRITEBLACK 8 // layer with sprites with black key color
#define LAYERMODE_SPRITEWHITE 9 // layer with sprites with white key color
#define LAYERMODE_FASTSPRITEKEY 10 // layer with fast sprites with key color
#define LAYERMODE_FASTSPRITEBLACK 11 // layer with fast sprites with black key color
#define LAYERMODE_FASTSPRITEWHITE 12 // layer with fast sprites with white key color
#define LAYERMODE_PERSPKEY 13 // layer with key color and image with transformation matrix
#define LAYERMODE_PERSPBLACK 14 // layer with black key color and image with transformation matrix
#define LAYERMODE_PERSPWHITE 15 // layer with white key color and image with transformation matrix
#define LAYERMODE_PERSP2KEY 16 // layer with key color and double-pixel image with transformation matrix
#define LAYERMODE_PERSP2BLACK 17 // layer with black key color and double-pixel image with transformation matrix
#define LAYERMODE_PERSP2WHITE 18 // layer with white key color and double-pixel image with transformation matrix
#define LAYERMODE_BASE 0 ///< Base layer
#define LAYERMODE_KEY 1 ///< Layer with key color
#define LAYERMODE_BLACK 2 ///< layer with black key color
#define LAYERMODE_WHITE 3 ///< Layer with white key color
#define LAYERMODE_MONO 4 ///< Layer with mono pattern
#define LAYERMODE_COLOR 5 ///< layer with simple color
#define LAYERMODE_RLE 6 ///< Layer with RLE compression
#define LAYERMODE_SPRITEKEY 7 ///< Layer with sprites with key color
#define LAYERMODE_SPRITEBLACK 8 ///< Layer with sprites with black key color
#define LAYERMODE_SPRITEWHITE 9 ///< Layer with sprites with white key color
#define LAYERMODE_FASTSPRITEKEY 10 ///< Layer with fast sprites with key color
#define LAYERMODE_FASTSPRITEBLACK 11 ///< Layer with fast sprites with black key color
#define LAYERMODE_FASTSPRITEWHITE 12 ///< Layer with fast sprites with white key color
#define LAYERMODE_PERSPKEY 13 ///< Layer with key color and image with transformation matrix
#define LAYERMODE_PERSPBLACK 14 ///< Layer with black key color and image with transformation matrix
#define LAYERMODE_PERSPWHITE 15 ///< Layer with white key color and image with transformation matrix
#define LAYERMODE_PERSP2KEY 16 ///< Layer with key color and double-pixel image with transformation matrix
#define LAYERMODE_PERSP2BLACK 17 ///< Layer with black key color and double-pixel image with transformation matrix
#define LAYERMODE_PERSP2WHITE 18 ///< Layer with white key color and double-pixel image with transformation matrix
#define LAYERMODE_NUM 19 // number of overlapped layer modes
#define LAYERMODE_NUM 19 ///< Number of overlapped layer modes
/// @}
// Structure of sprite sSprite (on change update structure sSprite in vga_layer.h)
#define SSPRITE_IMG 0 // u8* img; // pointer to image data

View File

@@ -12,9 +12,11 @@
#ifndef _PICOVGA_H
#define _PICOVGA_H
//!@addtogroup VideoInit Video/Library Initialization
//!@addtogroup VideoMode Configurating Video Mode
//!@addtogroup Screen Screen layout
/// @defgroup VideoInit Video/Library Initialization
/// @defgroup VideoMode Configurating Video Mode
/// @defgroup Screen Screen Layout
/// @defgroup Layers Overlay Layers
/// @defgroup Colors Colors and Palettes
typedef signed char s8;
typedef unsigned char u8;

View File

@@ -114,10 +114,12 @@ void ScanlineTypePrint(const u8* scan, int lines);
// - All layer modes must use same layer program (LAYERMODE_BASE = overlapped layers are OFF)
void VgaInit(const sVmode* vmode); //, u8 layer1mode=LAYERMODE_BASE, u8 layer2mode=LAYERMODE_BASE, u8 layer3mode=LAYERMODE_BASE);
//! @addtogroup VideoInit
//! @brief Functions for initialzing the library
//! @details The video mode can be initialized either simply by the Video() function or in more detail by the following functions.
//! @{
/**
* @addtogroup VideoInit
* @brief Functions for initialzing the library
* @details The video mode can be initialized either simply by the Video() function or in more detail by the following functions.
* @{
*/
/**
* @brief Start the VGA processing on core1
@@ -137,15 +139,17 @@ void StartVgaCore();
*/
void VgaInitReq(const sVmode* vmode);
//! @}
/// @}
//! @addtogroup Core Second core
//! @brief Execute functions on the second core
//! @details If the 2nd core is not too busy generating the video, it can be passed a request to perform the function.
//! This does not affect the video generation, it may just happen that the requested function runs slowly when the
//! generator is heavily loaded. The function cannot use interrupts, cannot disable interrupts, and may be restricted
//! from using the hardware interpolator (video interrupt does not save its state).
//! @{
/**
* @addtogroup Core Second core
* @brief Execute functions on the second core
* @details If the 2nd core is not too busy generating the video, it can be passed a request to perform the function.
* This does not affect the video generation, it may just happen that the requested function runs slowly when the
* generator is heavily loaded. The function cannot use interrupts, cannot disable interrupts, and may be restricted
* from using the hardware interpolator (video interrupt does not save its state).
* @{
*/
/**
* @brief Execute remote function on second core
@@ -163,7 +167,7 @@ Bool Core1Busy();
*/
void Core1Wait();
//!@}
/// @}
/**
* @brief Wait for VSync scanline

View File

@@ -72,124 +72,190 @@ extern const sLayerMode LayerMode[LAYERMODE_NUM];
// current layer mode of layers
extern u8 LayerModeInx[LAYERS]; // index of current layer mode (LAYERMODE_*)
extern sLayerMode CurLayerMode[LAYERS]; // copy of current layer mode
// layer screen descriptor (on change update SLAYER_* in define.h)
typedef struct {
const u8* img; // pointer to image in current layer format, or sprite list
const void* par; // additional parameter (RLE index table, integer transformation matrix)
u32 init; // init word sent on start of scanline (start X coordinate)
u32 keycol; // key color
u16 trans; // trans count
s16 x; // start X coordinate
s16 y; // start Y coordinate
u16 w; // width in pixels
u16 h; // height
u16 wb; // image width in bytes (pitch of lines)
u8 mode; // layer mode
s8 horiz; // horizon of perspective projection/4 (only with LAYERMODE_PERSP* modes, 0=no perspecitve, <0 ceilling)
u8 xbits; // number of bits of width of source image (only with LAYERMODE_PERSP* modes)
u8 ybits; // number of bits of height of source image (only with LAYERMODE_PERSP* modes)
u16 spritenum; // number of sprites
Bool on; // layer is ON
u8 cpp; // current clock pulses per pixel (used to calculate X coordinate)
} sLayer;
// sprite (on change update SSPRITE_* in define.h)
typedef struct {
u8* img; // SSPRITE_IMG pointer to image data
u8* x0; // SSPRITE_X0 pointer to array of start of lines, or fast sprite start of lines/4
u8* w0; // SSPRITE_W0 pointer to array of length of lines, or fast sprite length of lines/4
u32 keycol; // SSPRITE_KEYCOL key color
s16 x; // SSPRITE_X sprite X-coordinate on the screen
s16 y; // SSPRITE_Y sprite Y-coordinate on the screen
u16 w; // SSPRITE_W sprite width (slow sprite: max. width 255)
u16 h; // SSPRITE_H sprite height
u16 wb; // SSPRITE_WB sprite pitch (number of bytes between lines)
u16 res; // ...reserved, structure align
} sSprite;
// current layer screens
extern sLayer LayerScreen[LAYERS]; // layer screens
extern u8 LayerMask; // mask of active layers
// index of first pin of layer (base layer should stay VGA_GPIO_FIRST)
/**
* @addtogroup Layers
* @details The display of the image by the PicoVGA library is performed by the PIO processor controller. PIO0 is used.
* The other controller, PIO1, is unused and can be used for other purposes. PIO0 contains a 4 state machine, SM0 to SM3.
* All PIO0 state machines use a common program of 32 instructions. Each state machine serves 1 overlay layer. SM0 services
* base layer 0, along with servicing the synchronization signal. The base layer service program consists of 15 instructions,
* starting at offset 17. This part of the program is immutable and is always used. The other 3 layers, 1 to 3, SM1 to SM3,
* use the other part of the program memory, 17 instructions starting at address 0. This part may change, depending on the mode
* of the overlay layers. All 3 overlay layers use a common program and must therefore operate in the same display mode. Some
* overlay modes use the same program and can be shared - see the table below for details.
* @note Only base layer 0 can contain segments in different formats. Overlay layers 1 to 3 are independent of the base layer format, sharing only the total display area with the base layer, but using their own image format, for which only the coordinates and dimensions are specified.
* describes the contents of the display. The Raspberry Pico has a limited RAM size and cannot accommodate a high resolution image. Therefore, the image must be composed of smaller segments to minimize the memory-intensive parts.
* @{
*/
/// Layer screen descriptor (on change update SLAYER_* in define.h)
typedef struct {
const u8* img; ///< Pointer to image in current layer format, or sprite list
const void* par; ///< Additional parameter (RLE index table, integer transformation matrix)
u32 init; ///< Init word sent on start of scanline (start X coordinate)
u32 keycol; ///< Key color
u16 trans; ///< Trans count
s16 x; ///< Start X coordinate
s16 y; ///< Start Y coordinate
u16 w; ///< Width in pixels
u16 h; ///< Height
u16 wb; ///< Image width in bytes (pitch of lines)
u8 mode; ///< Layer mode
s8 horiz; ///< Horizon of perspective projection/4 (only with LAYERMODE_PERSP* modes, 0=no perspecitve, <0 ceilling)
u8 xbits; ///< Number of bits of width of source image (only with LAYERMODE_PERSP* modes)
u8 ybits; ///< Number of bits of height of source image (only with LAYERMODE_PERSP* modes)
u16 spritenum; ///< Number of sprites
Bool on; ///< Layer is ON
u8 cpp; ///< Current clock pulses per pixel (used to calculate X coordinate)
} sLayer;
/// Sprite (on change update SSPRITE_* in define.h)
typedef struct {
u8* img; ///< SSPRITE_IMG pointer to image data
u8* x0; ///< SSPRITE_X0 pointer to array of start of lines, or fast sprite start of lines/4
u8* w0; ///< SSPRITE_W0 pointer to array of length of lines, or fast sprite length of lines/4
u32 keycol; ///< SSPRITE_KEYCOL key color
s16 x; ///< SSPRITE_X sprite X-coordinate on the screen
s16 y; ///< SSPRITE_Y sprite Y-coordinate on the screen
u16 w; ///< SSPRITE_W sprite width (slow sprite: max. width 255)
u16 h; ///< SSPRITE_H sprite height
u16 wb; ///< SSPRITE_WB sprite pitch (number of bytes between lines)
u16 res; ///< Reserved, structure align
} sSprite;
/// Current layer screens
extern sLayer LayerScreen[LAYERS];
/// Index of first pin of layer (base layer should stay VGA_GPIO_FIRST)
extern u8 LayerFirstPin[LAYERS_MAX];
// number of pins of overlapped layer (base layer should stay VGA_GPIO_OUTNUM)
/// Number of pins of overlapped layer (base layer should stay VGA_GPIO_OUTNUM)
extern u8 LayerNumPin[LAYERS_MAX];
// set overlapped layer 1..3 ON
/**
* @brief Set overlapped layer 1..3 ON
* @param inx Layer index
*/
void LayerOn(u8 inx);
// set overlapped layer 1..3 OFF
/**
* @brief Set overlapped layer 1..3 OFF
* @param inx Layer index
*/
void LayerOff(u8 inx);
// set coordinate X of overlapped layer
/**
* @brief Set coordinate X of overlapped layer
* @param inx Layer index
* @param x X coordinate
*/
void LayerSetX(u8 inx, s16 x);
// set coordinate Y of overlapped layer
/**
* @brief Set coordinate Y of overlapped layer
* @param inx Layer index
* @param y Y coordinate
*/
void LayerSetY(u8 inx, s16 y);
// set width of image of overlapped layer
// Uses auto pitch wb (full line). Set custom wb after calling this function.
/**
* @brief Set width of image of overlapped layer
* @note Uses auto pitch wb (full line). Set custom wb after calling this function.
* @param inx Layer index
* @param w Width
*/
void LayerSetW(u8 inx, u16 w);
// set height of image of overlapped layer
/**
* @brief Set height of image of overlapped layer
* @param inx Layer index
* @param h Height
*/
void LayerSetH(u8 inx, u16 h);
// setup overlapped layer 1..3 (not for sprites and not for perspective mode)
// inx ... layer index 1..3
// img ... pointer to image data
// vmode ... pointer to initialized video configuration
// w ... image width in pixels (must be multiple of 4)
// h ... image height
// col ... key color (needed for LAYERMODE_KEY and LAYERMODE_MONO layer mode)
// par ... additional data (RLE index table, integer transformation matrix)
// Use these functions after layer setup: LayerSetX, LayerSetY, LayerOn
/**
* @brief Setup overlapped layer 1..3 (not for sprites or perspective mode)
* @details The function sets the dimensions of the image and its address. The coordinates are cleared. The position of the
* image on the screen can be set by the LayetSetX() and LayerSetY() functions. The coordinates do not depend on the graphic
* modes of the base layer and refer to the upper left corner of the active screen area. After initialization, the layer remains
* disabled. Layer visibility must be turned on by calling the LayerOn() function.
* @param inx Layer index 1..3
* @param img Pointer to image data
* @param vmode Pointer to initialized video configuration
* @param w Image width in pixels (must be multiple of 4)
* @param h Image height
* @param col Key color (Needed for LAYERMODE_KEY and LAYERMODE_MONO. For both *BLACK and *WHITE modes, specify COL_BLACK or 0)
* @param par Additional data (RLE index table, integer transformation matrix)
*/
void LayerSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 col = 0, const void* par = NULL);
// setup overlapped layer 1..3 for LAYERMODE_PERSP* modes
// inx ... layer index 1..3
// img ... pointer to source image data (image width and height must be power of 2)
// vmode ... pointer to initialized video configuration
// w ... destination image width in pixels (must be multiple of 4)
// h ... destination image height
// xbits ... number of bits of width of source image
// ybits ... number of bits of height of source image
// horiz ... horizon of perspective projection/4 (0=no perspecitve, <0 ceilling)
// mat ... integer transformation matrix
// col ... key color (needed for LAYERMODE_PERSPKEY layer mode)
// Use these functions after layer setup: LayerSetX, LayerSetY, LayerOn
/**
* @brief Setup overlapped layer 1..3 for LAYERMODE_PERSP* modes
* @details In contrast to the LayerSetup() function, the dimensions of the source image in number of bits (the image dimensions
* must be a power of 2), the height of the horizon/4 (for a negative value the floor turns into a ceiling, for zero the
* perspective transformation is not applied) and the pointer to the transformation matrix in integer form are also specified.
* @param inx Layer index 1..3
* @param img Pointer to source image data (image width and height must be power of 2)
* @param vmode Pointer to initialized video configuration
* @param w Destination image width in pixels (must be multiple of 4)
* @param h Destination image height
* @param xbits Number of bits of width of source image
* @param ybits Number of bits of height of source image
* @param horiz Horizon of perspective projection/4 (0=no perspecitve, <0 ceilling)
* @param mat Integer transformation matrix
* @param col Key color (needed for LAYERMODE_PERSPKEY layer mode)
*/
void LayerPerspSetup(u8 inx, const u8* img, const sVmode* vmode, u16 w, u16 h, u8 xbits, u8 ybits,
s8 horiz, const int* mat, u8 col = 0);
// setup overlapped layer 1..3 for LAYERMODE_SPRITE* and LAYERMODE_FASTSPRITE* modes
// inx ... layer index 1..3
// sprite ... pointer to list of sprites (array of pointers to sprites; sorted by X on LAYERMODE_FASTSPRITE* modes)
// spritenum ... number of sprites in the list (to turn sprite off, you can set its coordinate Y out of the screen)
// vmode ... pointer to initialized video configuration
// x ... start coordinate X of area with sprites
// y ... start coordinate Y of area with sprites
// w ... width of area with sprites (must be multiple of 4)
// h ... height of area with sprites
// col ... key color (needed for LAYERMODE_SPRITEKEY and LAYERMODE_FASTSPRITEKEY layer mode)
// Use functions LayerOn after layer setup.
/**
* @brief Setup overlapped layer 1..3 for LAYERMODE_SPRITE* and LAYERMODE_FASTSPRITE* modes
* @details It differs from the other setup functions by specifying the coordinate of the sprite area, the pointer to the
* sprite address array and the number of sprites.
* @param inx Layer index 1..3
* @param sprite Pointer to list of sprites (array of pointers to sprites; sorted by X on LAYERMODE_FASTSPRITE* modes)
* @param spritenum Number of sprites in the list (to turn sprite off, you can set its coordinate Y out of the screen)
* @param vmode Pointer to initialized video configuration
* @param x Start coordinate X of area with sprites
* @param y Start coordinate Y of area with sprites
* @param w Width of area with sprites (must be multiple of 4)
* @param h Height of area with sprites
* @param col Key color (needed for LAYERMODE_SPRITEKEY and LAYERMODE_FASTSPRITEKEY layer mode)
*/
void LayerSpriteSetup(u8 inx, sSprite** sprite, u16 spritenum, const sVmode* vmode,
s16 x, s16 y, u16 w, u16 h, u8 col = 0);
// prepare array of start and length of lines (detects transparent pixels)
// img ... image
// x0 ... array of start of lines
// w0 ... array of length of lines
// w ... sprite width (slow sprite: max. width 255)
// h ... sprite height
// wb ... sprite pitch (bytes between lines)
// col ... key color
// fast ... fast sprite, divide start and length of line by 4
/**
* @brief Prepare array of start and length of lines (detects transparent pixels)
* @details The function will be passed a pointer to the image of each sprite (only 8-bit sprites are supported), the image
* dimensions, the pointers to the array of origin and line lengths (the array dimensions correspond to the height of the sprite),
* and the key transparency color. The function searches for line starts and line ends and writes them into the fields.
* The 'fast' parameter specifies whether the tables are generated for fast sprites, in which case the line starts and lengths
* are divided by 4. For slow sprites, the sprite width must be limited to 255 pixels.
* @param img Pointer to image
* @param x0 Array of start of lines
* @param w0 Array of length of lines
* @param w Sprite width (slow sprite: max. width 255)
* @param h Sprite height
* @param wb Sprite pitch (bytes between lines)
* @param col Key color
* @param fast Fast sprite, divide start and length of line by 4
*/
void SpritePrepLines(const u8* img, u8* x0, u8* w0, u16 w, u16 h, u16 wb, u8 col, Bool fast);
// sort fast sprite list by X coordinate
/**
* @brief Sort fast sprite list by X coordinate
* @details Fast sprites require sorting the list by the X coordinate. Pass a pointer to the list of sprites and the number of
* sprites in the list. This function should be called whenever you change the X coordinate of the sprite. Transient conditions
* (e.g. momentary mis-overlapping of sprites) do not matter, they are just short-term optical errors, they do not compromise
* the program. The function sorts using the bubble method, so it is quite slow, but so far it does not seem to harm anything
* (there are not many sprays).
* @param list Sprite list
* @param num Number of sprites
*/
void SortSprite(sSprite** list, int num);
/// @}
#endif // _VGA_LAYER_H

View File

@@ -8,43 +8,49 @@
#ifndef _VGA_PAL_H
#define _VGA_PAL_H
#define MULTICOL(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24)) // multiply color pattern (used in mode GF_COLOR)
/**
* @addtogroup Colors
* @{
*/
/// Multiply color pattern (used in mode GF_COLOR)
#define MULTICOL(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
// CGA colors
#define CGACOL_0 0 // 0x000000 black
#define CGACOL_1 2 // 0x0000C3 dark blue
#define CGACOL_2 20 // 0x00C300 dark green
#define CGACOL_3 22 // 0x00C3C3 dark cyan
#define CGACOL_4 160 // 0xC30000 dark red
#define CGACOL_5 162 // 0xC300C3 dark magenta
#define CGACOL_6 168 // 0xC35400 brown
#define CGACOL_7 182 // 0xC3C3C3 light gray
#define CGACOL_8 73 // 0x545454 dark gray
#define CGACOL_9 75 // 0x5454FF light blue
#define CGACOL_10 93 // 0x54FF54 light green
#define CGACOL_11 95 // 0x54FFFF light cyan
#define CGACOL_12 233 // 0xFF5454 light red
#define CGACOL_13 235 // 0xFF54FF light magenta
#define CGACOL_14 253 // 0xFFFF54 yellow
#define CGACOL_15 255 // 0xFFFFFF white
#define CGACOL_0 0 ///< CGA 0x000000 black
#define CGACOL_1 2 ///< CGA 0x0000C3 dark blue
#define CGACOL_2 20 ///< CGA 0x00C300 dark green
#define CGACOL_3 22 ///< CGA 0x00C3C3 dark cyan
#define CGACOL_4 160 ///< CGA 0xC30000 dark red
#define CGACOL_5 162 ///< CGA 0xC300C3 dark magenta
#define CGACOL_6 168 ///< CGA 0xC35400 brown
#define CGACOL_7 182 ///< CGA 0xC3C3C3 light gray
#define CGACOL_8 73 ///< CGA 0x545454 dark gray
#define CGACOL_9 75 ///< CGA 0x5454FF light blue
#define CGACOL_10 93 ///< CGA 0x54FF54 light green
#define CGACOL_11 95 ///< CGA 0x54FFFF light cyan
#define CGACOL_12 233 ///< CGA 0xFF5454 light red
#define CGACOL_13 235 ///< CGA 0xFF54FF light magenta
#define CGACOL_14 253 ///< CGA 0xFFFF54 yellow
#define CGACOL_15 255 ///< CGA 0xFFFFFF white
// ZX Spectrum color
#define ZXCOL_0 0 // 0x000000 black
#define ZXCOL_1 2 // 0x0000C3 dark blue
#define ZXCOL_2 160 // 0xC30000 dark red
#define ZXCOL_3 162 // 0xC300C3 dark magenta
#define ZXCOL_4 20 // 0x00C300 dark green
#define ZXCOL_5 22 // 0x00C3C3 dark cyan
#define ZXCOL_6 180 // 0xC3C300 dark yellow
#define ZXCOL_7 182 // 0xC3C3C3 light gray
#define ZXCOL_8 73 // 0x545454 dark gray
#define ZXCOL_9 3 // 0x0000FF light blue
#define ZXCOL_10 224 // 0xFF0000 light red
#define ZXCOL_11 227 // 0xFF00FF light magenta
#define ZXCOL_12 28 // 0x00FF00 light green
#define ZXCOL_13 31 // 0x00FFFF light cyan
#define ZXCOL_14 252 // 0xFFFF00 yellow
#define ZXCOL_15 255 // 0xFFFFFF white
#define ZXCOL_0 0 ///< ZX Spectrum 0x000000 black
#define ZXCOL_1 2 ///< ZX Spectrum 0x0000C3 dark blue
#define ZXCOL_2 160 ///< ZX Spectrum 0xC30000 dark red
#define ZXCOL_3 162 ///< ZX Spectrum 0xC300C3 dark magenta
#define ZXCOL_4 20 ///< ZX Spectrum 0x00C300 dark green
#define ZXCOL_5 22 ///< ZX Spectrum 0x00C3C3 dark cyan
#define ZXCOL_6 180 ///< ZX Spectrum 0xC3C300 dark yellow
#define ZXCOL_7 182 ///< ZX Spectrum 0xC3C3C3 light gray
#define ZXCOL_8 73 ///< ZX Spectrum 0x545454 dark gray
#define ZXCOL_9 3 ///< ZX Spectrum 0x0000FF light blue
#define ZXCOL_10 224 ///< ZX Spectrum 0xFF0000 light red
#define ZXCOL_11 227 ///< ZX Spectrum 0xFF00FF light magenta
#define ZXCOL_12 28 ///< ZX Spectrum 0x00FF00 light green
#define ZXCOL_13 31 ///< ZX Spectrum 0x00FFFF light cyan
#define ZXCOL_14 252 ///< ZX Spectrum 0xFFFF00 yellow
#define ZXCOL_15 255 ///< ZX Spectrum 0xFFFFFF white
// Colors
// GP0 ... B0 ... VGA B0 blue
@@ -99,25 +105,23 @@
#define COL_WHITE COL_GRAY7
// compose color from RGB
/// compose color from RGB
#define COLRGB(r,g,b) ((u8)(((r)&0xe0)|(((g)&0xe0)>>3)|((b)>>6)))
// default 16-color palettes (CGA colors)
// - do not set "const", to stay in faster RAM
extern u8 DefPal16[16];
/// default 16-color palettes (CGA colors)
extern u8 DefPal16[16]; // - do not set "const", to stay in faster RAM
// ZX Spectrum color palettes
// - do not set "const", to stay in faster RAM
extern u8 ZXPal16[16];
/// ZX Spectrum color palettes
extern u8 ZXPal16[16]; // - do not set "const", to stay in faster RAM
// 4-color palettes (CGA colors)
// - do not set "const", to stay in faster RAM
extern u8 PalCGA1[4]; // palette 0, low intensity (black, dark green, brown)
extern u8 PalCGA2[4]; // palette 0, high intensity (black, light green, light red, yellow)
extern u8 PalCGA3[4]; // palette 1, low intensity (black, dark cyan, dark magenta, light gray)
extern u8 PalCGA4[4]; // palette 1, high intensity (black, light cyan, light magenta, white)
extern u8 PalCGA5[4]; // palette 1, low intensity (black, dark cyan, dark red, light gray)
extern u8 PalCGA6[4]; // palette 1, high intensity (black, light cyan, light red, white)
extern u8 PalCGA1[4]; ///< 4-color CGA palette 0, low intensity (black, dark green, brown)
extern u8 PalCGA2[4]; ///< 4-color CGA palette 0, high intensity (black, light green, light red, yellow)
extern u8 PalCGA3[4]; ///< 4-color CGA palette 1, low intensity (black, dark cyan, dark magenta, light gray)
extern u8 PalCGA4[4]; ///< 4-color CGA palette 1, high intensity (black, light cyan, light magenta, white)
extern u8 PalCGA5[4]; ///< 4-color CGA palette 1, low intensity (black, dark cyan, dark red, light gray)
extern u8 PalCGA6[4]; ///< 4-color CGA palette 1, high intensity (black, light cyan, light red, white)
// 4-color palette translation table
//extern u32 Pal4Trans[256];
@@ -128,14 +132,24 @@ extern u8 PalCGA6[4]; // palette 1, high intensity (black, light cyan, light red
//extern u16 ZX16Trans[256];
// values of color components
extern u8 RGVal[8]; // values of Red and Green components
extern u8 BVal[4]; // values of Blue components
extern u8 RGVal[8]; ///< Values of Red and Green components
extern u8 BVal[4]; ///< Values of Blue components
// distance of 2 colors in 332 format (R3G3B2)
// - returns value 0..195075
/**
* @brief Distance of 2 colors in 332 format (R3G3B2)
* @param col1 First color
* @param col2 Second color
* @returns Distance value 0..195075
*/
int ColDist(u8 col1, u8 col2);
// generate gradient
/**
* @brief Generate gradient
* @param dst Destination
* @param w Width
*/
void GenGrad(u8* dst, int w);
/// @}
#endif // _VGA_PAL_H

View File

@@ -8,48 +8,52 @@
#ifndef _VGA_SCREEN_H
#define _VGA_SCREEN_H
//!@addtogroup Screen
//!@brief Defining the layout of the display
//!@details When displaying screen image, the default pointer is pScreen for the library. It points to the sScreen structure that
//!describes the contents of the display. The Raspberry Pico has a limited RAM size and cannot accommodate a high resolution image. Therefore, the image must be composed of smaller segments to minimize the memory-intensive parts.
//!@note The following descriptions of the image format only apply to the base image layer 0. It is the only one that can contain
//!segments in different formats. Overlay layers 1 through 3 are independent of the base layer format, sharing only the total
//!screen area with the base layer but using their own image format.
//!@{
/**
* @addtogroup Screen
* @brief Defining the layout of the display
* @details When displaying screen image, the default pointer is pScreen for the library. It points to the sScreen structure that
* describes the contents of the display. The Raspberry Pico has a limited RAM size and cannot accommodate a high resolution image.
* Therefore, the image must be composed of smaller segments to minimize the memory-intensive parts.
* @note The following descriptions of the image format only apply to the base image layer 0. It is the only one that can contain
* segments in different formats. Overlay layers 1 through 3 are independent of the base layer format, sharing only the total
* screen area with the base layer but using their own image format.
* @{
*/
//! Video segment (on change update SSEGM_* in define.h)
/// Video segment (on change update SSEGM_* in define.h)
typedef struct {
u16 width; //!< SSEGM_WIDTH width of this video segment in pixels (must be multiple of 4, 0=inactive segment)
u16 wb; //!< SSEGM_WB pitch - number of bytes between lines
s16 offx; //!< SSEGM_OFFX display offset at X direction (must be multiple of 4)
s16 offy; //!< SSEGM_OFFY display offset at Y direction
u16 wrapx; //!< SSEGM_WRAPX wrap width in X direction (number of pixels, must be multiply of 4 and > 0)
//!< text modes: wrapx must be multiply of 8
u16 wrapy; //!< SSEGM_WRAPY wrap width in Y direction (number of lines, cannot be 0)
const void* data; //!< SSEGM_DATA pointer to video buffer with image data
u8 form; //!< SSEGM_FORM graphics format GF_*
bool dbly; //!< SSEGM_DBLY double Y (2 scanlines per 1 image line)
u16 par3; //!< SSEGM_PAR3 parameter 3
u32 par; //!< SSEGM_PAR parameter 1
u32 par2; //!< SSEGM_PAR2 parameter 2
u16 width; ///< SSEGM_WIDTH width of this video segment in pixels (must be multiple of 4, 0=inactive segment)
u16 wb; ///< SSEGM_WB pitch - number of bytes between lines
s16 offx; ///< SSEGM_OFFX display offset at X direction (must be multiple of 4)
s16 offy; ///< SSEGM_OFFY display offset at Y direction
u16 wrapx; ///< SSEGM_WRAPX wrap width in X direction (number of pixels, must be multiply of 4 and > 0)
///< text modes: wrapx must be multiply of 8
u16 wrapy; ///< SSEGM_WRAPY wrap width in Y direction (number of lines, cannot be 0)
const void* data; ///< SSEGM_DATA pointer to video buffer with image data
u8 form; ///< SSEGM_FORM graphics format GF_*
bool dbly; ///< SSEGM_DBLY double Y (2 scanlines per 1 image line)
u16 par3; ///< SSEGM_PAR3 parameter 3
u32 par; ///< SSEGM_PAR parameter 1
u32 par2; ///< SSEGM_PAR2 parameter 2
} sSegm;
//! Video strip (on change update SSTRIP_* in define.h)
/// Video strip (on change update SSTRIP_* in define.h)
typedef struct {
u16 height; //!< SSTRIP_HEIGHT height of this strip in number of scanlines
u16 num; //!< SSTRIP_NUM number of video segments
sSegm seg[SEGMAX]; //!< SSTRIP_SEG list of video segments
u16 height; ///< SSTRIP_HEIGHT height of this strip in number of scanlines
u16 num; ///< SSTRIP_NUM number of video segments
sSegm seg[SEGMAX]; ///< SSTRIP_SEG list of video segments
} sStrip;
//! Video screen (on change update SSCREEN_* in define.h)
/// Video screen (on change update SSCREEN_* in define.h)
typedef struct {
u16 num; //!< SSCREEN_NUM number of video strips
u16 backup; //!< SSCREEN_BACKUP backup number of video strips during display OFF
sStrip strip[STRIPMAX]; //!< SSCREEN_STRIP list of video strips
u16 num; ///< SSCREEN_NUM number of video strips
u16 backup; ///< SSCREEN_BACKUP backup number of video strips during display OFF
sStrip strip[STRIPMAX]; ///< SSCREEN_STRIP list of video strips
} sScreen;
extern sScreen Screen; //!< Default video screen
extern sScreen* pScreen; //!< Pointer to current video screen
extern sScreen Screen; ///< Default video screen
extern sScreen* pScreen; ///< Pointer to current video screen
/**
* @brief Clear screen (set 0 strips, does not modify sprites)
@@ -546,6 +550,6 @@ void ScreenSegmTilePersp3(sSegm* segm, const u8* map, const u8* tiles, const int
void ScreenSegmTilePersp4(sSegm* segm, const u8* map, const u8* tiles, const int* mat,
u8 mapwbits, u8 maphbits, u8 tilebits, s8 horizon);
//!@}
/// @}
#endif // _VGA_SCREEN_H

View File

@@ -8,222 +8,224 @@
#ifndef _VGA_VMODE_H
#define _VGA_VMODE_H
//! @addtogroup VideoMode
//! @brief Structures and functions for configuring video modes
//! @details The sVgaCfg structure contains the required properties of the video mode: the display resolution,
//! the minimum processor frequency and the timing of the sVideo signal, possibly also the required overlay mode.
//! You can first call the VgaCfgDef() function, which presets the structure to the default parameters. The VgaCfg()
//! function prepares the sVmode descriptor structure, which is later passed to the VgaInitReq() function.
//! At this point no operations are taking place only the necessary settings are being calculated. After the calculation,
//! some items of the sVmode structure can be adjusted. In the library there are global structures Cfg and Vmode that can
//! be used for the function. The required screen resolution and signal timing are two independent properties.
//! For timing, you are limited only by the number of video lines of the image, but otherwise you can set any screen resolution
//! within them. For example, for PAL and NTSC video, you can set a VGA video resolution. To make the program versatile so that
//! it can be run on both a VGA monitor and a TV, use a VGA resolution of 640x480 or 320x240 (or 512x400 and 256x192, due to RAM
//! limitations). When changing the display, just select VGA/PAL or NTSC timing, the resolution does not change for the program.
//! @{
/**
* @addtogroup VideoMode
* @brief Structures and functions for configuring video modes
* @details The sVgaCfg structure contains the required properties of the video mode: the display resolution,
* the minimum processor frequency and the timing of the sVideo signal, possibly also the required overlay mode.
* You can first call the VgaCfgDef() function, which presets the structure to the default parameters. The VgaCfg()
* function prepares the sVmode descriptor structure, which is later passed to the VgaInitReq() function.
* At this point no operations are taking place only the necessary settings are being calculated. After the calculation,
* some items of the sVmode structure can be adjusted. In the library there are global structures Cfg and Vmode that can
* be used for the function. The required screen resolution and signal timing are two independent properties.
* For timing, you are limited only by the number of video lines of the image, but otherwise you can set any screen resolution
* within them. For example, for PAL and NTSC video, you can set a VGA video resolution. To make the program versatile so that
* it can be run on both a VGA monitor and a TV, use a VGA resolution of 640x480 or 320x240 (or 512x400 and 256x192, due to RAM
* limitations). When changing the display, just select VGA/PAL or NTSC timing, the resolution does not change for the program.
* @{
*/
#define VIDEO_NAME_LEN 5 //!< length of video timing name
#define VIDEO_NAME_LEN 5 ///< length of video timing name
//! Video timings structure
/// Video timings structure
typedef struct {
// horizontal
float htot; //!< Horizontal total scanline in [us]
float hfront; //!< Horizontal front porch (after image, before HSYNC) in [us]
float hsync; //!< Horizontal sync pulse in [us]
float hback; //!< Horizontal back porch (after HSYNC, before image) in [us]
float hfull; //!< Horizontal full visible in [us] (corresponding to 'wfull' pixels)
float htot; ///< Horizontal total scanline in [us]
float hfront; ///< Horizontal front porch (after image, before HSYNC) in [us]
float hsync; ///< Horizontal sync pulse in [us]
float hback; ///< Horizontal back porch (after HSYNC, before image) in [us]
float hfull; ///< Horizontal full visible in [us] (corresponding to 'wfull' pixels)
// vertical
u16 vtot; //!< Vertical total scanlines (both subframes)
u16 vmax; //!< Vertical maximal height
u16 vtot; ///< Vertical total scanlines (both subframes)
u16 vmax; ///< Vertical maximal height
// subframe 1
u16 vsync1; //!< V sync (half-)pulses on subframe 1
u16 vpost1; //!< V sync post half-pulses on subframe 1
u16 vback1; //!< V back porch (after VSYNC, before image) on subframe 1
u16 vact1; //!< active visible scanlines, subframe 1
u16 vfront1; //!< V front porch (after image, before VSYNC) on subframe 1
u16 vpre1; //!< V sync pre half-pulses on subframe 1
u16 vsync1; ///< V sync (half-)pulses on subframe 1
u16 vpost1; ///< V sync post half-pulses on subframe 1
u16 vback1; ///< V back porch (after VSYNC, before image) on subframe 1
u16 vact1; ///< active visible scanlines, subframe 1
u16 vfront1; ///< V front porch (after image, before VSYNC) on subframe 1
u16 vpre1; ///< V sync pre half-pulses on subframe 1
// subframe 2 (ignored if not interlaced)
u16 vsync2; //!< V sync half-pulses on subframe 2
u16 vpost2; //!< V sync post half-pulses on subframe 2
u16 vback2; //!< V back porch (after VSYNC, before image) on subframe 2
u16 vact2; //!< active visible scanlines, subframe 2
u16 vfront2; //!< V front porch (after image, before VSYNC) on subframe 2
u16 vpre2; //!< V sync pre half-pulses on subframe 2
u16 vsync2; ///< V sync half-pulses on subframe 2
u16 vpost2; ///< V sync post half-pulses on subframe 2
u16 vback2; ///< V back porch (after VSYNC, before image) on subframe 2
u16 vact2; ///< active visible scanlines, subframe 2
u16 vfront2; ///< V front porch (after image, before VSYNC) on subframe 2
u16 vpre2; ///< V sync pre half-pulses on subframe 2
// name
const char* name; //!< video timing name (VIDEO_NAME_LEN characters + terminating 0)
const char* name; ///< video timing name (VIDEO_NAME_LEN characters + terminating 0)
// flags
bool inter; //!< interlaced (use subframes)
bool psync; //!< positive synchronization
bool odd; //!< first sub-frame is odd lines 1, 3, 5,... (PAL)
bool inter; ///< interlaced (use subframes)
bool psync; ///< positive synchronization
bool odd; ///< first sub-frame is odd lines 1, 3, 5,... (PAL)
} sVideo;
// === TV videomodes
//! TV PAL interlaced 5:4 720x576 (4:3 768x576, 16:9 1024x576)
/// TV PAL interlaced 5:4 720x576 (4:3 768x576, 16:9 1024x576)
extern const sVideo VideoPAL;
//! TV PAL progressive 5:4 360x288 (4:3 384x288, 16:9 512x288)
/// TV PAL progressive 5:4 360x288 (4:3 384x288, 16:9 512x288)
extern const sVideo VideoPALp;
//! TV NTSC interlaced 4:3 640x480 (5:4 600x480, 16:9 848x480)
/// TV NTSC interlaced 4:3 640x480 (5:4 600x480, 16:9 848x480)
extern const sVideo VideoNTSC;
//! TV NTSC progressive 4:3 320x240 (5:4 300x240, 16:9 424x240)
/// TV NTSC progressive 4:3 320x240 (5:4 300x240, 16:9 424x240)
extern const sVideo VideoNTSCp;
// === Monitor videomodes
//! EGA 8:5 640x400 (5:4 500x400, 4:3 528x400, 16:9 704x400), vert. 70 Hz, hor. 31.4685 kHz, pixel clock 25.175 MHz
/// EGA 8:5 640x400 (5:4 500x400, 4:3 528x400, 16:9 704x400), vert. 70 Hz, hor. 31.4685 kHz, pixel clock 25.175 MHz
extern const sVideo VideoEGA;
//! VGA 4:3 640x480 (16:9 848x480), vert. 60 Hz, hor. 31.4685 kHz, pixel clock 25.175 MHz
/// VGA 4:3 640x480 (16:9 848x480), vert. 60 Hz, hor. 31.4685 kHz, pixel clock 25.175 MHz
extern const sVideo VideoVGA;
//! SVGA 4:3 800x600 (16:9 1064x600), vert. 60 Hz, hor. 37.897 kHz, pixel clock 40 MHz
/// SVGA 4:3 800x600 (16:9 1064x600), vert. 60 Hz, hor. 37.897 kHz, pixel clock 40 MHz
extern const sVideo VideoSVGA;
//! XGA 4:3 1024x768 (16:9 1360x768), vert. 60 Hz, hor. 48.36310 kHz, pixel clock 65 MHz
/// XGA 4:3 1024x768 (16:9 1360x768), vert. 60 Hz, hor. 48.36310 kHz, pixel clock 65 MHz
extern const sVideo VideoXGA;
//! VESA 4:3 1152x864, vert. 60 Hz, hor. 53.697 kHz, pixel clock 81.62 MHz
/// VESA 4:3 1152x864, vert. 60 Hz, hor. 53.697 kHz, pixel clock 81.62 MHz
extern const sVideo VideoVESA;
//! HD 4:3 1280x960, vert. 53 Hz, hor. 51.858 kHz, pixel clock 102.1 MHz
/// HD 4:3 1280x960, vert. 53 Hz, hor. 51.858 kHz, pixel clock 102.1 MHz
extern const sVideo VideoHD;
//! Required configuration to initialize VGA output
/// Required configuration to initialize VGA output
typedef struct {
u16 width; //!< Width in pixels
u16 height; //!< Height in lines
u16 wfull; //!< Width of full screen, corresponding to 'hfull' time (0=use 'width' parameter)
const sVideo* video; //!< Used video timings
u32 freq; //!< Required minimal system frequency in kHz (real frequency can be higher)
u32 fmax; //!< Maximal system frequency in kHz (limit resolution if needed)
u8 mode[LAYERS_MAX]; //!< Modes of overlapped layers 0..3 LAYERMODE_* (LAYERMODE_BASE = layer is off)
//!< - mode of layer 0 is ignored (always use LAYERMODE_BASE)
//!< - all overlapped layers must use same layer program
bool dbly; //!< double in Y direction
bool lockfreq; //!< Lock required frequency, do not change it
u16 width; ///< Width in pixels
u16 height; ///< Height in lines
u16 wfull; ///< Width of full screen, corresponding to 'hfull' time (0=use 'width' parameter)
const sVideo* video; ///< Used video timings
u32 freq; ///< Required minimal system frequency in kHz (real frequency can be higher)
u32 fmax; ///< Maximal system frequency in kHz (limit resolution if needed)
u8 mode[LAYERS_MAX]; ///< Modes of overlapped layers 0..3 LAYERMODE_* (LAYERMODE_BASE = layer is off)
///< - mode of layer 0 is ignored (always use LAYERMODE_BASE)
///< - all overlapped layers must use same layer program
bool dbly; ///< double in Y direction
bool lockfreq; ///< Lock required frequency, do not change it
} sVgaCfg;
//! Videomode table - used to setup video driver
/// Videomode table - used to setup video driver
typedef struct {
// screen resolution
u16 width; //!< Screen width in pixels
u16 height; //!< Screen height in lines
u16 wfull; //!< Screen width of full screen (corresponding to 'hfull' time)
u16 wmax; //!< Screen maximal width (corresponding to 'hmax' time)
u16 width; ///< Screen width in pixels
u16 height; ///< Screen height in lines
u16 wfull; ///< Screen width of full screen (corresponding to 'hfull' time)
u16 wmax; ///< Screen maximal width (corresponding to 'hmax' time)
// setup PLL system clock
u32 freq; //!< system clock frequency in kHz
u32 vco; //!< VCO frequency in kHz
u16 fbdiv; //!< fbdiv PLL divider
u8 pd1; //!< postdiv1
u8 pd2; //!< postdiv2
u32 freq; ///< system clock frequency in kHz
u32 vco; ///< VCO frequency in kHz
u16 fbdiv; ///< fbdiv PLL divider
u8 pd1; ///< postdiv1
u8 pd2; ///< postdiv2
// setup PIO state machine
u16 div; //!< PIO divide base state machine clock
u16 cpp; //!< State machine clocks per pixel
u8 prog; //!< Layer program LAYERPROG_*
u8 mode[LAYERS_MAX]; //!< mode of layer 0..3 LAYERMODE_* (LAYERMODE_BASE = layer is off or base layer)
u16 div; ///< PIO divide base state machine clock
u16 cpp; ///< State machine clocks per pixel
u8 prog; ///< Layer program LAYERPROG_*
u8 mode[LAYERS_MAX]; ///< mode of layer 0..3 LAYERMODE_* (LAYERMODE_BASE = layer is off or base layer)
// horizontal timings
u16 htot; //!< Total state machine clocks per line
u16 hfront; //!< H front porch in state machine clocks (min. 2)
u16 hsync; //!< H sync pulse in state machine clocks (min. 4)
u16 hback; //!< H back porch in state machine clocks (min. 13)
float hfreq; //!< Horizontal frequency in [Hz]
u16 htot; ///< Total state machine clocks per line
u16 hfront; ///< H front porch in state machine clocks (min. 2)
u16 hsync; ///< H sync pulse in state machine clocks (min. 4)
u16 hback; ///< H back porch in state machine clocks (min. 13)
float hfreq; ///< Horizontal frequency in [Hz]
// vertical timings
u16 vtot; //!< Total scanlines (both sub-frames)
u16 vmax; //!< Maximal height
float vfreq; //!< Vertical frequency in [Hz]
u16 vtot; ///< Total scanlines (both sub-frames)
u16 vmax; ///< Maximal height
float vfreq; ///< Vertical frequency in [Hz]
// subframe 1
u16 vsync1; //!< V sync (half-)pulses on subframe 1
u16 vpost1; //!< V sync post (half-)pulses on subframe 1
u16 vback1; //!< V back porch (after VSYNC, before image) on subframe 1
u16 vact1; //!< active visible scanlines, subframe 1
u16 vfront1; //!< V front porch (after image, before VSYNC) on subframe 1
u16 vpre1; //!< V sync pre (half-)pulses on subframe 1
u16 vfirst1; //!< first active scanline, subframe 1
u16 vsync1; ///< V sync (half-)pulses on subframe 1
u16 vpost1; ///< V sync post (half-)pulses on subframe 1
u16 vback1; ///< V back porch (after VSYNC, before image) on subframe 1
u16 vact1; ///< active visible scanlines, subframe 1
u16 vfront1; ///< V front porch (after image, before VSYNC) on subframe 1
u16 vpre1; ///< V sync pre (half-)pulses on subframe 1
u16 vfirst1; ///< first active scanline, subframe 1
// subframe 2 (ignored if not interlaced)
u16 vsync2; //!< V sync half-pulses on subframe 2
u16 vpost2; //!< V sync post half-pulses on subframe 2
u16 vback2; //!< V back porch (after VSYNC, before image) on subframe 2
u16 vact2; //!< active visible scanlines, subframe 2
u16 vfront2; //!< V front porch (after image, before VSYNC) on subframe 2
u16 vpre2; //!< V sync pre half-pulses on subframe 2
u16 vfirst2; //!< first active scanline, subframe 2
u16 vsync2; ///< V sync half-pulses on subframe 2
u16 vpost2; ///< V sync post half-pulses on subframe 2
u16 vback2; ///< V back porch (after VSYNC, before image) on subframe 2
u16 vact2; ///< active visible scanlines, subframe 2
u16 vfront2; ///< V front porch (after image, before VSYNC) on subframe 2
u16 vpre2; ///< V sync pre half-pulses on subframe 2
u16 vfirst2; ///< first active scanline, subframe 2
// name
const char* name; //!< Video timing name (VIDEO_NAME_LEN characters + terminating 0)
const char* name; ///< Video timing name (VIDEO_NAME_LEN characters + terminating 0)
// flags
bool lockfreq; //!< Lock current frequency, do not change it
bool dbly; //!< Double scanlines
bool inter; //!< Interlaced (use sub-frames)
bool psync; //!< Positive synchronization
bool odd; //!< First sub-frame is odd lines 1, 3, 5,... (PAL)
bool lockfreq; ///< Lock current frequency, do not change it
bool dbly; ///< Double scanlines
bool inter; ///< Interlaced (use sub-frames)
bool psync; ///< Positive synchronization
bool odd; ///< First sub-frame is odd lines 1, 3, 5,... (PAL)
} sVmode;
//! Output device
/// Output device
enum {
DEV_PAL = 0, //!< PAL TV
DEV_NTSC, //!< NTSC TV
DEV_VGA, //!< VGA monitor
DEV_PAL = 0, ///< PAL TV
DEV_NTSC, ///< NTSC TV
DEV_VGA, ///< VGA monitor
DEV_MAX
};
//! Preset videomode resolution
/// Preset videomode resolution
enum {
RES_ZX = 0, //!< 256x192
RES_CGA, //!< 320x200
RES_QVGA, //!< 320x240
RES_EGA, //!< 512x400
RES_VGA, //!< 640x480
RES_SVGA, //!< 800x600 (not for TV device)
RES_XGA, //!< 1024x768 (not for TV device)
RES_HD, //!< 1280x960 (not for TV device)
RES_ZX = 0, ///< 256x192
RES_CGA, ///< 320x200
RES_QVGA, ///< 320x240
RES_EGA, ///< 512x400
RES_VGA, ///< 640x480
RES_SVGA, ///< 800x600 (not for TV device)
RES_XGA, ///< 1024x768 (not for TV device)
RES_HD, ///< 1280x960 (not for TV device)
RES_MAX
};
//! Graphics formats
/// Graphics formats
enum {
FORM_8BIT = 0, //!< 8-bit pixel graphics (up to EGA resolution)
FORM_4BIT, //!< 4-bit pixel graphics (up to SVGA graphics)
FORM_MONO, //!< 1-bit pixel graphics
FORM_TILE8, //!< 8x8 tiles
FORM_TILE12, //!< 12x12 tiles
FORM_TILE16, //!< 16x16 tiles
FORM_TILE24, //!< 24x24 tiles
FORM_TILE32, //!< 32x32 tiles
FORM_TILE48, //!< 48x48 tiles
FORM_TILE64, //!< 64x64 tiles
FORM_MTEXT8, //!< mono text with font 8x8
FORM_MTEXT16, //!< mono text with font 8x16
FORM_TEXT8, //!< attribute text with font 8x8
FORM_TEXT16, //!< attribute text with font 8x16
FORM_RLE, //!< images with RLE compression (on overlapped layer 1)
FORM_8BIT = 0, ///< 8-bit pixel graphics (up to EGA resolution)
FORM_4BIT, ///< 4-bit pixel graphics (up to SVGA graphics)
FORM_MONO, ///< 1-bit pixel graphics
FORM_TILE8, ///< 8x8 tiles
FORM_TILE12, ///< 12x12 tiles
FORM_TILE16, ///< 16x16 tiles
FORM_TILE24, ///< 24x24 tiles
FORM_TILE32, ///< 32x32 tiles
FORM_TILE48, ///< 48x48 tiles
FORM_TILE64, ///< 64x64 tiles
FORM_MTEXT8, ///< mono text with font 8x8
FORM_MTEXT16, ///< mono text with font 8x16
FORM_TEXT8, ///< attribute text with font 8x8
FORM_TEXT16, ///< attribute text with font 8x16
FORM_RLE, ///< images with RLE compression (on overlapped layer 1)
FORM_MAX
};
extern sVmode Vmode; //!< Videomode setup
extern sVgaCfg Cfg; //!< Required configuration
extern sCanvas Canvas; //!< Canvas of draw box
extern sVmode Vmode; ///< Videomode setup
extern sVgaCfg Cfg; ///< Required configuration
extern sCanvas Canvas; ///< Canvas of draw box
//! 16-color palette translation table
/// 16-color palette translation table
extern u16 Pal16Trans[256];
/**
@@ -247,10 +249,10 @@ void VgaPrintCfg(const sVmode* vmode);
*/
void VgaCfg(const sVgaCfg* cfg, sVmode* vmode);
//! @}
/// @}
//! @addtogroup VideoInit
//! @{
/// @addtogroup VideoInit
/// @{
/**
* @brief Simplified initialization of the video mode
@@ -271,7 +273,7 @@ void VgaCfg(const sVgaCfg* cfg, sVmode* vmode);
*/
void Video(u8 dev, u8 res, u8 form, u8* buf, const void* buf2 = FontBoldB8x16);
//! @}
/// @}
#endif // _VGA_VMODE_H