GFXlib 2 - FreeBASIC's gfx library ---------------------------------- Copyright (C) 2005 Angelo Mottola (a.mottola@libero.it) Welcome to GFXlib 2. This library is meant to supply FB with an emulation of the QB built-in gfx routines, but also to give users more possibilities than QB provided, like high resolutions and hi/truecolor, MMX optimized routines, mouse and keyboard (multiple keypresses) handling, transparent PUT support with clipping done right, multiple offscreen pages in any gfx mode. It also supports setting up an OpenGL mode so you can do your own OpenGL coding without worrying about platform dependent initializations. This document holds a reference of the available functions in alphabetical order, together with small inline examples where appropriate and with remarked differences with their QB counterparts. You'll also find some appendices for special topics. Be sure to have a look at Appendix F, as it provides many hints and shows some of the new features GFXlib comes with. Some useful constants are defined in the fbgfx.bi include file for you to use, you may want to have a look at it, it's in your FreeBASIC/inc directory. Note that this include file is not mandatory for using GFXlib; it is just provided to supply some useful constants, nothing more. Happy coding! Index ------------------------------------------------------------------------------ Functions reference: BLOAD statement BSAVE statement CIRCLE statement COLOR statement DRAW statement FLIP statement GET statement GETJOYSTICK statement GETMOUSE statement IMAGECREATE function IMAGEDESTROY statement INP function LINE statement MULTIKEY function OUT statement PAINT statement PALETTE statement PCOPY statement PMAP statement POINT function PSET statement PUT statement RGB macro RGBA macro SCREEN statement SCREENCOPY statement SCREENINFO statement SCREENLIST function SCREENLOCK statement SCREENPTR function SCREENRES statement SCREENSET statement SCREENSYNC statement SCREENUNLOCK statement SETMOUSE statement VIEW statement WAIT statement WINDOW statement WINDOWTITLE statement Appendix A: DOS keyboard scancodes Appendix B: Default palettes Appendix C: Internal pixel formats Appendix D: About speed and size Appendix E: Internal drivers Appendix F: Hints ============================================================================== FUNCTIONS REFERENCE ============================================================================== +-------+--------------------------------------------------------------------- | BLOAD | +-------+ Statement to load a block of binary data from a file. Syntax: BLOAD filename[,addr] Argument: Description: filename Name of the file to load data from. addr Address where to load data. If omitted or 0 (NULL), data is loaded on the current work page. Insights: BLOAD can be used to save a block of binary data, and can be also used to load raw pixel data to the screen: if you don't specify the addr argument, or you set it to 0, the data will be treated as pixel data and loaded into the current work page. BLOAD "image.bsv", 0 is infact equivalent to: SCREENLOCK BLOAD "image.bsv", SCREENPTR SCREENUNLOCK Pay attention that the pixel data stored in the file is in the same pixel format as the one used by the current video mode; see appendix C for details. BLOAD can also be used to load BMP files; when this is the case, if addr is zero, the BMP will be loaded on the screen, otherwise it'll be loaded in GET/PUT format into the specified addr address. In both cases the BMP pixel data will be converted to the current pixel format, and if the BMP has an associated palette this will be loaded and set as current palette. Loading a BMP will fail if a screen mode was not previously set, or if the image is a truecolor bitmap and the current gfx mode is a paletted mode. Example: DIM image(64004) AS UBYTE SCREEN 13 BLOAD "image.bmp", VARPTR(image(0)) PUT (0,0), image Differences from QB: FB version supports blocks of data with sizes bigger than 64K and BMP files loading. See also: BSAVE, SCREEN, GET, PUT, Appendix C. +-------+--------------------------------------------------------------------- | BSAVE | +-------+ Statement to save a block of binary data into a file. Syntax: BSAVE filename,addr,size Argument: Description: filename Name of the file where data will be saved. addr Address where to save data from. If 0 (NULL), data is taken from current work page. size Size of the data block to be saved, in bytes. Insights: BSAVE saves a block of binary data into a specified file. It can also be used to save pixel data from current work page into a file, by specifying 0 as addr argument: BSAVE "image.bsv", 0, 64000 is infact equivalent to: SCREENLOCK BSAVE "image.bsv", SCREENPTR, 64000 SCREENUNLOCK When saving pixel data, the data will be saved in the current gfx mode pixel format; see appendix C for details. Also keep in mind a pixel may require more than one byte, so the size argument will need to be adjusted accordingly. BSAVE can also be used to save BMP image files; it is sufficient the specified filename has a .bmp extension. In this case the size argument is ignored, and the image dimensions will be deducted automatically from either the screen mode, either the GET/PUT buffer, depending on if addr is 0 or not. Example: none Differences from QB: Files saved using the FB version of BSAVE are incompatible with files saved using the QB BSAVE. See also: BLOAD, Appendix C. +--------+-------------------------------------------------------------------- | CIRCLE | +--------+ Statement to draw circles, ellipses or arcs. Syntax: CIRCLE [buffer,][STEP](x,y),radius[,[color][,[start][,[end][,[aspect] [,F]]]]] Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. STEP The STEP option specify that x and y are offsets relative to the current graphics cursor position. x,y Coordinates of the center radius Radius color Color attribute. This is mode specific, see COLOR and SCREEN for details. start,end Start and end angles in radians. These can range -2PI to 2PI; if you specify a negative angle, its value is changed sign and a line is drawn from the center up to that point in the arc. End angle can be less than start angle. If you do not specify start and end, a full circle/ellipse is drawn; if you you specify start but not end, end is assumed to be 2PI; if you specify end but not start, start is assumed to be 0. aspect Aspect ratio, or the ratio of the y radius over the x radius. The default value is the value required to draw a perfect circle on the screen, keeping pixel aspect ratio in mind. So this value can be calculated as follows: ratio = (y_radius / x_radius) * pixel_aspect_ratio Where pixel_aspect_ratio is the ratio of the current mode width over the current mode height, assuming a 4:3 standard monitor. If aspect ratio is less than 1, radius is the x radius; if aspect is more or equal to 1, radius is the y radius. F If you specify this flag, the circle/ellipse will be filled with the selected color. This has no effect if you're drawing an arc. Insights: Use this function to draw circles, ellipses or arcs. Custom coordinates system set up by WINDOW and/or VIEW affect the drawing operation; clipping set by VIEW also applies. When CIRCLE finishes drawing, the current graphics cursor position is set to the supplied center. Example: ' Set 640x480 mode and draws a circle in the center SCREEN 18 CIRCLE (320, 240), 200, 15 ' Draws a filled ellipse CIRCLE (320, 240), 200, 2, , , 0.2, F ' Draws a small arc CIRCLE (320, 240), 200, 4, 0.83, 1.67, 3 Differences from QB: As this function uses a different algorithm from the one used in QB, circles, ellipses and arcs may not be equal pixel-by-pixel to those produced by QB. In addition, this version supports filled circles/ellipses via the F flag, whereas QB doesn't. See also: SCREEN, COLOR. +-------+--------------------------------------------------------------------- | COLOR | +-------+ Statement to set current foreground/background colors. Syntax: COLOR [foreground][,background] Argument: Description: foreground New foreground color value. background New background color value. Insights: The COLOR statement sets the current foreground and/or background colors. CIRCLE, DRAW, LINE, CLS, PAINT, PRINT and PSET all use the last colors set by this function when you don't specify a color to them, where applicable. The color values COLOR accepts depend on the current gfx mode: Mode 1: foreground is screen color (ranging 0-15). background modulo 4 is the emulated CGA palette to be used: 0: green, red, and brown. 1: cyan, magenta and white. 2: same as 0, but with bright colors. 3: same as 1, but with bright colors. Modes 2 and 11: foreground is a color index in current palette (ranging 0-1). background is a color index in current palette (ranging 0-1). Modes 7 and 8: foreground is a color index in current palette (ranging 0-15). background is screen color index in current palette (ranging 0-15). Mode 9: foreground is a color index in current palette (ranging 0-63). background is screen color index in current palette (ranging 0-63). Mode 12: foreground is a color index in current palette (ranging 0-15). background is a color index in current palette (ranging 0-15). Modes 13 and up: foreground is a color index in current palette (ranging 0-255). background is a color index in current palette (ranging 0-255). If you are using a color depth higher than 8bpp, foreground and background are direct RGB color values in the form &hRRGGBB, where RR, GG and BB are the red, green and blue components ranging &h00-&hFF (0-255 in decimal notation). While in hi/truecolor modes, you can also use the RGB function to obtain a valid color value. Example: ' Sets 800x600 in 32bpp color depth SCREEN 19, 32 ' Sets orange foreground and dark blue background color COLOR &hFF8000, &h000040 ' Say hello CLS LOCATE 19, 44: PRINT "Hello World!" SLEEP Differences from QB: FB version accepts direct color values in hi/truecolor modes; COLOR in screen mode 1 accepts 4 different CGA palettes instead of the 2 supported by QB. See also: SCREEN, PALETTE. +------+---------------------------------------------------------------------- | DRAW | +------+ Statement for sequenced pixel plotting. Syntax: DRAW [buffer,]commands Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. commands String holding drawing commands, see below. Insights: The DRAW statement can be used to issue several drawing commands all at once; it is useful to quickly draw figures. The command string accepts the following commands: Command: Description: Commands to plot pixels: B Optional prefix; move but do not draw. N Optional prefix; draw but do not move. Mx,y Move to specified screen location; if + or - precedes x, movement is relative to current cursor position. U[n] Move n units up. If n is omitted, 1 is assumed. D[n] Move n units down. If n is omitted, 1 is assumed. L[n] Move n units left. If n is omitted, 1 is assumed. R[n] Move n units right. If n is omitted, 1 is assumed. E[n] Move n units up and right. If n is omitted, 1 is assumed. F[n] Move n units down and right. If n is omitted, 1 is assumed. G[n] Move n units down and left. If n is omitted, 1 is assumed. H[n] Move n units up and left. If n is omitted, 1 is assumed. Commands to color: Cn Changes current foreground color to n. Pp,b Flood fills region with border color b with color p. Commands to scale and rotate: Sn Sets the current unit length; default is 4 pixels per unit. An Rotate n*90 degrees (n ranges 0-3). TAn Rotate n degrees (n ranges 0-359). Extra commands: Xp Executes commands at address p. For example, you could do: down10$ = "D10" : DRAW "U10R5X" + VARPTR(down10$) + "L5" Example: none Differences from QB: none See also: none +------+---------------------------------------------------------------------- | FLIP | +------+ Alias for PCOPY and SCREENCOPY. See SCREENCOPY for details. +-----+----------------------------------------------------------------------- | GET | +-----+ Statement to save a block of pixels data into an array for later use. Syntax: GET [buffer,][STEP](x1,y1)-[STEP](x2,y2), arrayname[(idx)] Argument: Description: buffer Buffer were to get pixel data from. If omitted, data is taken from the current work page. x1,y1,x2,y2 Coordinates of the opposite corners of the graphics blocks to retrieve. STEP STEP specifies a pair of coordinates is relative to the last graphics cursor position. STEP before the second pair of coordinates specifies those are relative to the first pair. arrayname Array where to save the graphical block idx Index into arrayname where to begin storing data. If idx is omitted, it is assumed to be 0. Insights: Use this function to save blocks of graphics so you can later use PUT to draw them. The coordinates of the block are affected by the most recent WINDOW and VIEW statements, and must be both inside the current clipping region set by VIEW. If the enclosed region does not entirely fit into the clipping region GET will have no effect and an illegal function call error will be thrown. The supplied array must be large enough to hold the block you're going to save; the required array size depends on both the block size in pixels and the current color depth. Use the following formula to compute the right size in bytes: For color depths 1, 2, 4 and 8: size = 4 + (w * h) For color depths 15 and 16: size = 4 + (w * h * 2) For color depths 24 and 32: size = 4 + (w * h * 4) Where w and h are the width and height of the graphics block you want to save. Assuming you're working with INTEGER arrays, and as an INTEGER in FB is 4 bytes long, to save an 8bpp 32x32 block for example, you'll need an array of (((4 + (w * h)) + 3) / 4) elements. Example: See PUT example. Differences from QB: Contrary to the QB version, this requested array size for an image does not reduce if you are using a mode with color depth less than 8bpp; so your arrays will need to be sized using the formula for 8bpp modes even if you're is 1, 2 or 4bpp modes. Also pay attention when storing pixel data blocks in multidimensional arrays, as QB stored arrays in column-order, whereas FB stores arrays in row-order, so what in QB was achieved with PUT (100, 100), sprites(0, 7), in FB is achieved with PUT (100, 100), sprites(7, 0). See also: PUT, SCREEN, WINDOW, VIEW. +-------------+--------------------------------------------------------------- | GETJOYSTICK | +-------------+ Statement to retrieve joystick position and buttons status Syntax: GETJOYSTICK id,buttons[,[x][,[y][,[z][,[r][,[u][,v]]]]]] Argument: Description: id Joystick ID number. Valid IDs range 0-15. buttons On function termination, this will return a bitmask holding buttons status. Each bit is 1 if the corresponding button is currently pressed, 0 otherwise. x,y On function termination, these will hold the current x,y axes position of the given joystick, ranging -1.0 to 1.0. z,r,u,v Additional joystick axes for which to fetch current position. Returned values range -1.0 to 1.0. Insights: This function is used to get the status of a given joystick device, identified by an unique numeric ID. Up to 16 joysticks are supported, with the ID ranging 0-15. Once GETJOYSTICK is called, it'll return the joystick buttons/axes status in the parameters passed by reference to it. Buttons must be an integer variable and will hold a bitmask specifying which joystick buttons are currently pressed; up to 32 buttons are supported, and the first button status is reported in the least significant bit. Axes information is returned in the remaining single variables passed to the function; the returned axis value will range -1.0 to 1.0, with 0.0 being the still position. A joystick will always at least support the x,y axes, but it may also support other axes. If an additional axis is available, its status will be returned in the corresponding variable and will also range -1.0 to 1.0; if the axis is not available, a value strictly less than -1.0 will be returned. If the joystick with specified ID number is not available, buttons will hold -1, and all axes will hold a value strictly less than -1.0. Example: ' Set video mode and enter loop DIM x AS SINGLE, y AS SINGLE, throttle AS SINGLE, buttons AS INTEGER SCREEN 13 DO ' Get buttons, x, y, and 3rd axis status of joystick 0; assumes ' 3rd axis to be throttle. Discard other axes. GETJOYSTICK 0, buttons, x, y, throttle LOCATE 1, 1 IF x < -1.0 THEN PRINT "Joystick 0 not available" ELSE PRINT "Joystick 0:" PRINT USING " Position: ##.##:##.##"; x; y PRINT USING " Throttle: ##.##"; throttle PRINT " Buttons: " + BIN$(buttons) + SPACE$(32) END IF LOOP WHILE INKEY$ = "" END Differences from QB: Function new in FB. See also: GETMOUSE, MULTIKEY. +----------+------------------------------------------------------------------ | GETMOUSE | +----------+ Statement to retrieve mouse position and buttons status Syntax: GETMOUSE x,y[,wheel,[buttons]] Argument: Description: x,y Mouse position in screen coordinates is stored in these variables on function termination. If mouse is not present or out of the program window, x and y will hold -1. wheel Mouse wheel counter. Rotating the wheel away from you makes the count to increase, rotating towards you makes it to decrease. If mouse is not present or out of the program window, wheel will hold -1. buttons On function termination, this will return a bitmask holding buttons status. Bit 0 is set if left mouse button is down; bit 1 is set if right mouse button is down; bit 2 is set if middle mouse button is down. Insights: Use this function to get mouse info while in gfx mode. Pay attention: GETMOUSE does NOT work if a gfx mode is not set. Pass x, y, wheel and buttons variables by reference, so this function will store result values in them. If mouse is not present or out of the program window, all returned values will be -1. Example: ' Set video mode and enter loop DIM x AS INTEGER, y AS INTEGER, buttons AS INTEGER SCREEN 13 DO ' Get mouse x, y and buttons. Discard wheel position. GETMOUSE x, y, , buttons LOCATE 1, 1 IF x < 0 THEN PRINT "Mouse not available or not on window" ELSE PRINT USING "Mouse position: ###:### Buttons: "; x; y; IF buttons AND 1 THEN PRINT "L"; IF buttons AND 2 THEN PRINT "R"; IF buttons AND 4 THEN PRINT "M"; PRINT " " END IF LOOP WHILE INKEY$ = "" END Differences from QB: Function new in FB. See also: SETMOUSE, SCREEN, MULTIKEY, GETJOYSTICK. +-------------+--------------------------------------------------------------- | IMAGECREATE | +-------------+ Function to create a new image buffer. Syntax: IMAGECREATE(width,height[,color]) Argument: Description: width,height Size of the image in pixels. color Optional color with which to clear the image upon creation. If omitted, defaults to the trasparent color. Insights: Use this function to allocate and set up a memory buffer for pixel data; once created, the image can be used as target to all gfx primitives. Upon creation, the image is cleared to color if specified, otherwise it is cleared to the transparent color for the current color depth, that is, 0 for indexed modes and &hFF00FF for hi/truecolor modes. IMAGECREATE returns a pointer to the allocated image block, and will succeed only if a gfx mode has already been set by calling SCREEN or SCREENRES; on failure, 0 is returned. Images created by IMAGECREATE must be freed by calling IMAGEDESTROY once you are done using them in order to free allocated memory. Example: DIM buffer AS ANY PTR SCREEN 15, 32 buffer = IMAGECREATE(64, 64, RGBA(64, 160, 0, 255)) CIRCLE buffer, (32, 32), 28, RGBA(255, 0, 0, 128),,,,F PUT (160, 120), buffer, PSET PUT (180, 140), buffer, ALPHA IMAGEDESTROY buffer Differences from QB: Function new in FB. See also: IMAGEDESTROY, SCREEN, SCREENRES. +--------------+-------------------------------------------------------------- | IMAGEDESTROY | +--------------+ Function to free the memory allocated for an image created by IMAGECREATE. Syntax: IMAGEDESTROY image Argument: Description: image The image to be freed. Insights: IMAGEDESTROY frees the memory allocated for the given image, assuming it was previously created by calling IMAGECREATE. Example: none Differences from QB: Function new in FB. See also: IMAGECREATE. +-----+----------------------------------------------------------------------- | INP | +-----+ Function for VGA port input emulation. Syntax: INP(port) Argument: Description: port Emulated VGA port number to read from. Insights: This function emulates the QB INP function for VGA port access; the only port value this function accepts is &h3C9. You do not normally need this function; use 8bit or higher color depth modes and PALETTE instead. Example: none Differences from QB: This is just a limited emulation, and only port &h3C9 is supported for DOS VGA palette DAC registers reading operations. A read from any other port will return 0. See also: PALETTE, OUT, WAIT. +------+---------------------------------------------------------------------- | LINE | +------+ Statement for line/box drawing. Syntax: LINE [buffer,][[STEP](x1,y1)]-[STEP](x2,y2)[,[color[,[B[F]][,style]]] Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. STEP Forces given coordinate to be relative to last graphical cursor position. When used before second pair of coordinates the position is relative to first pair. x1,y1,x2,y2 Position of start and end points. If start point is omitted, last graphical cursor position is assumed. color Color to be used for drawing, in the same format supported by the COLOR statement. If you omit this, current foreground color is assumed. B Draws the outlines of a box instead of a line, treating (x1,y1) and (x2,y2) as the opposite corners of the box. Style does not apply in this case. BF Same as B, but draws a filled box. style 16bit bitmask value to be used for styled line drawing. Starting from most significant bit, for each pixel of the line the style bit is tested and if not set, the pixel is not drawn. Each 16 pixels the bit position is reset to the most significant bit of the 16bit style mask. Insights: LINE coordinates are affected by last WINDOW and VIEW statements, and respect clipping rect set by VIEW. Example: none Differences from QB: none See also: CIRCLE, WINDOW, VIEW. +----------+------------------------------------------------------------------ | MULTIKEY | +----------+ Function to detect multiple keypresses Syntax: MULTIKEY(scancode) Argument: Description: scancode The DOS hardware scancode of the key you want to query for. Insights: This function lets you detect the immediate status of any key at any time; the returned value is -1 if key is pressed, 0 otherwise. The keyboard input buffer is not disabled while you use MULTIKEY; that is, pressed keys will be stored and subsequently returned by your next call to INKEY$. This means you have to empty INKEY$ when you finish using MULTIKEY: WHILE INKEY$ <> "": WEND Keeping INKEY$ to work while you use MULTIKEY allows more flexibility and can be useful to detect CHR$(255)+"X" combo returned on window close button click. Pay attention: this function does only work if you are in gfx mode; it does NOT work in console mode. For a list of accepted scancodes, see appendix A. Example: DIM work_page AS INTEGER, x AS INTEGER, y AS INTEGER ' Request 640x480 with 2 pages SCREEN 18, ,2 COLOR 2, 15 work_page = 0 x = 320 y = 240 DO ' Let's work on a page while we display the other one SCREENSET work_page, work_page XOR 1 ' Check arrow keys and update position accordingly IF MULTIKEY(&h4B) AND x > 0 THEN x = x - 1 IF MULTIKEY(&h4D) AND x < 639 THEN x = x + 1 IF MULTIKEY(&h48) AND y > 0 THEN y = y - 1 IF MULTIKEY(&h50) AND y < 479 THEN y = y + 1 CLS CIRCLE(x, y), 30, , , , ,F ' Page flip work_page = work_page XOR 1 LOOP WHILE NOT MULTIKEY(&h1) ' Clear input buffer WHILE INKEY$ <> "": WEND ' Restore both work and visible pages to page 0 SCREENSET PRINT "Press any key to exit..." SLEEP Differences from QB: Function new in FB. See also: SCREEN, INKEY$, Appendix A. +-----+----------------------------------------------------------------------- | OUT | +-----+ Statement for VGA port output emulation. Syntax: OUT port,value Argument: Description: port Emulated VGA port number to write to. value Byte value to be written. Insights: Used for lowlevel VGA palette management emulation, this function only accepts port numbers &h3C7, &h3C8 and &h3C9. You do not normally need this function; use 8bit or higher color depth modes and PALETTE instead. Example: none Differences from QB: This is just a limited emulation, and only ports &h3C7, &h3C8 and &h3C9 are supported for DOS VGA palette DAC registers writing operations. A write to any other port will have no effect. See also: PALETTE, INP, WAIT. +-------+--------------------------------------------------------------------- | PAINT | +-------+ Statement for flood-filling a screen region. Syntax: PAINT [buffer,][STEP](x,y)[,[paint][,bordercolor]] Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. STEP Forces given coordinate to be relative to last graphical cursor position. x,y Coordinates where to begin filling operation. paint Paint color or pattern, see below. If you omit this argument, current foreground color is used. bordercolor Color of the border in the same format as used by the COLOR statement. Filling stops when a pixel of this color is encountered. Insights: This function flood-fills a region of the screen, starting at specified coordinates, which are affected by last call to WINDOW and VIEW. Clipping region set by VIEW is respected. If the paint argument is a number, it is assumed a color in the same format used by the COLOR statement, and the region is flood-filled using that color. If paint is a string, the region will be filled using a pattern; the pattern is always 8x8 pixels, and the passed string must hold pixels data in a format dependent on the current color depth. The string holds pattern pixels row by row, and its size should be as follows: For color depths 1, 2, 4 and 8: size = 8 * 8 = 64 For color depths 15 and 16: size = (8 * 8) * 2 = 128 For color depths 24 and 32: size = (8 * 8) * 4 = 256 If the passed string is smaller, missing pixels will be 0. Flood-filling continues until pixels of the specified border color are found. Example: none Differences from QB: The QB additional background parameter is not supported. See also: COLOR, WINDOW, VIEW. +---------+------------------------------------------------------------------- | PALETTE | +---------+ Statement to set or get current palette. Syntax: PALETTE [GET] [index,color] PALETTE [GET] [index,r,g,b] PALETTE [GET] USING arrayname(idx) Argument: Description: index Index of the color to be set/get. color Packed color RGB value for specified index. r Color red component, ranging 0-255. g Color green component, ranging 0-255. b Color blue component, ranging 0-255. arrayname(idx) Array of packed RGB color values to be set, or destination array for current palette packed RGB color values. Insights: The PALETTE statement is used to customize the current palette for gfx modes with a color depth of up to 8bpp; using PALETTE while in a mode with a higher color depth will have no effect. Calling PALETTE with no argument restores the default palette for current gfx mode. If you specify index and color, these are dependent on the current mode: Screen mode: | index range: | color range: -----------------------------------+--------------+-------------- 1 | 0-3 | 0-15 2 | 0-1 | 0-15 7, 8 | 0-15 | 0-15 9 | 0-15 | 0-63 11 | 0-1 | see below 12 | 0-15 | see below 13, 14, 15, 16, 17, 18, 19, 20, 21 | 0-255 | see below In screen modes 1, 2, 7, 8 and 9 you can assign to each color index one of the colors in the available range. In other screen modes, the color must be specified in the packed form &hBBGGRR, where BB, GG and RR are the blue, green and red components ranging &h0-&h3F in hexadecimal (0-63 in decimal). If you don't like hexadecimal form, you can use the following formula to compute the integer value to pass to this parameter: color = red or (green shl 8) or (blue shl 16) Where red, green and blue must range 0-63. You can also specify the new color red, green and blue components directly, by calling PALETTE with 4 parameters. In this case r, g and b must be in the range 0-255. The available colors are reset by the SCREEN statement to a default palette; see appendix B for details. You can alter the contents of the current palette using the PALETTE statement for modes with a color depth higher or equal to 8, or by using the OUT statement in lower depth modes. Calling PALETTE USING allows to set a list of color values all at once; you should pass an array holding enough elements as the color indices available for your current gfx mode color depth (2 for 1bpp, 4 for 2bpp, 16 for 4bpp or 256 for 8bpp). The array elements must be integer values holding packed colors in the form described above. The colors stored into arrayname starting with given idx index are then assigned to each palette index, starting with index 0. Any change to the palette is immediately visible on screen. If the GET option is specified, PALETTE retrieves instead of setting color values for the current palette. The parameters have the same meaning as specified for the set form, but in this case color, r, g and b must be variables that will hold the color RGB values on function exit. Example: none Differences from QB: none See also: SCREEN, COLOR, OUT, Appendix B. +-------+--------------------------------------------------------------------- | PCOPY | +-------+ Alias for FLIP and SCREENCOPY, but requires both arguments. See SCREENCOPY for details. +------+---------------------------------------------------------------------- | PMAP | +------+ Function to map coordinates between view and physical mapping. Syntax: PMAP(expr, func) Argument: Description: expr Expression indicating the coordinate to be mapped. func Mapping function number to be applied to given coordinate. Insights: This function allows to convert a coordinate between view (as defined by the WINDOW statement) and physical (as set by the VIEW statement) mappings. Depending on the value of func, expr is used to compute a different mapping to be returned by PMAP: func value: return value: 0 Treats expr as x view coordinate and returns corresponding x physical coordinate. 1 Treats expr as y view coordinate and returns corresponding y physical coordinate. 2 Treats expr as x physical coordinate and returns corresponding x view coordinate. 3 Treats expr as y physical coordinate and returns corresponding y view coordinate. Example: none Differences from QB: none See also: VIEW, WINDOW. +-------+--------------------------------------------------------------------- | POINT | +-------+ Function to read a pixel color or coordinate. Syntax: POINT(x,y[,buffer]) POINT(func) Argument: Description: buffer Buffer were to get pixel from. If omitted, pixel is taken from current work page. x,y Coordinates of the pixel. func Specify which coordinate mapping to return. Insights: When called with two arguments, the specified (x,y) coordinates are affected by the most recent WINDOW and VIEW statements; if the pixel lies out of the current clipping region, POINT returns -1, otherwise a color number in the same format as used by the COLOR statement. When called with one argument, this function allows to retrieve the current gfx cursor position; POINT returns a value dependent on the func argument: func: return value: 0 Current x physical coordinate. 1 Current y physical coordinate. 2 Current x view coordinate. If the WINDOW statement has not been used, this returns the same as POINT(0). 3 Current y view coordinate. If the WINDOW statement has not been used, this returns the same as POINT(1). Example: none Differences from QB: none See also: COLOR, VIEW, WINDOW. +------+---------------------------------------------------------------------- | PSET | +------+ Statement to plot a single pixel. Syntax: PSET [buffer,][STEP](x,y) [,color] Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. STEP The STEP option specify that x and y are offsets relative to the current graphics cursor position. x,y Coordinates of the pixel. color Color attribute. This is mode specific, see COLOR and SCREEN for details. Insights: This function plots a single pixel on the screen. The x and y coordinates are affected by the last call to the VIEW and WINDOW statements, and respect the current clipping region as set by the VIEW statement. If you do not specify color, current foreground color is used. Example: none Differences from QB: none See also: POINT, VIEW, WINDOW. +-----+----------------------------------------------------------------------- | PUT | +-----+ Statement to draw a block of pixels previously saved by GET. Syntax: PUT [buffer,][STEP](x,y), arrayname[(idx)] [,mode[,(alpha|blender)]] Argument: Description: buffer Buffer were drawing takes place. If omitted, drawing occurs into current work page. STEP The STEP option specify that x and y are offsets relative to the current graphics cursor position. x,y Coordinates where to place the top-left corner of the block to be drawn. arrayname Array holding saved block pixels data. idx Index into arrayname where data is assumed to start. If idx is omitted, it is assumed to be 0. mode One of PSET, PRESET, AND, OR, XOR, TRANS or ALPHA; see below. If omitted, this defaults to XOR. alpha Uniform alpha value for sprite blending; see below. blender Pointer to custom blender function; see below. Insights: PUT can be used to draw images previously saved by the GET statement or created by the IMAGECREATE function. The x and y coordinates are affected by the last call to the VIEW and WINDOW statements, and plotted image respects the current clipping region set by last call to the VIEW statement. Pixels stored in given array (source pixels) are drawn on the screen interacting with the pixels onto which they are going to be drawn (destination pixels); the interaction depends on the mode parameter: mode: interaction: PSET Source pixels overwrite destination pixels. PRESET Source pixels are 1-complement negated and written over destination pixels. AND Destination pixels are bitwise ANDed with source pixels. OR Destination pixels are bitwise ORed with source pixels. XOR Destination pixels are bitwise XORed with source pixels. TRANS Source pixels overwrite destination pixels. If a source pixel is the mask color (see below), the pixel is skipped. ALPHA Source pixels are blended on top of destination pixels accordingly to either the source pixel alpha value, either the value specified in the alpha parameter, if present. CUSTOM Source pixels are blended on top of destination pixels accordingly to the user-specified function passed in the blender parameter. The AND, OR and XOR modes produce different results depending on the current color depth, as pixels are stored in different formats; see appendix C for details. If the TRANS mode is used, pixels using the mask color are not drawn. The mask color depends on the current color depth: in paletted modes (up to 8 bpp) it is equal to color index 0, while on hi/truecolor modes (15, 16, 24 and 32 bpp) it is equal to color &hFF00FF (bright pink). If the ALPHA mode is used, you can also specify an optional alpha parameter, ranging 0-255. If the alpha parameter is present, PUT will use it for all the pixels of your sprite, and will skip mask colors like in the TRANS mode; this will work only if you're in 15, 16, 24 or 32bit color depth. If you omit the alpha parameter, PUT will only work if you're in 32bit color depth, and it will use the alpha values embedded in each pixel; pixels using the mask color will not be skipped in this case, as it is assumed the sprite has a properly set up alpha channel. If the CUSTOM mode is used, you must also specify the blender parameter, which must be a pointer to a function of the form: FUNCTION MyBlender (BYVAL src AS UINTEGER, BYVAL dest AS UINTEGER) AS UINTEGER Such a function will be called for each pixel of your sprite, will receive the source sprite pixel and the destination pixel where it is going to be drawn, and must return the new pixel to be drawn. All color values are in the same format as accepted by all other gfx primitives, that is color indices for paletted modes, and &hRRGGBB values for hi/truecolor modes. The pixels data stored in given array must be compatible with current gfx mode color depth; that is, if you acquire an image using GET and you later change screen mode via SCREEN, the image data may not be valid in the new gfx mode, making PUT to behave badly. Example: ' Set 320x240 mode using 16bpp color depth SCREEN 14, 16 ' Let's allocate space for a 32x32 sprite DIM sprite((32 * 32 * 2) + 4) AS UBYTE ' Let's prepare our sprite LINE (0,0)-(31,31), &hFF0000, BF LINE (0,0)-(31,31), &h00FF00, B LINE (8,8)-(23,23), &hFF00FF, BF LINE (1,1)-(30,30), &h0000FF LINE (30,1)-(1,30), &h0000FF GET (0,0)-(31,31), sprite ' Showtime! CLS FOR i = 0 TO 63 v = ABS(SIN(CSNG(i) / 8.0)) * 255.0 LINE (0,i)-(319,i), RGB(v, v, v) NEXT i PUT (12, 16), sprite, PSET PUT (56, 16), sprite, PRESET PUT (100, 16), sprite, AND PUT (144, 16), sprite, OR PUT (188, 16), sprite, XOR PUT (232, 16), sprite, TRANS PUT (276, 16), sprite, ALPHA, 96 SLEEP Differences from QB: FB version supports hi/truecolor sprites, transparency, alpha blending and clipping. For modes with color depth up to 8bpp, it always assumes 1 byte equals 1 pixel into arrayname, whereas QB packs more pixels per byte if color depth is less than 8bpp. See also: GET, SCREEN. +-----+----------------------------------------------------------------------- | RGB | +-----+ Macro to compute valid color value for hi/truecolor modes. Syntax: RGB(red,green,blue) Argument: Description: red,green,blue Red, green and blue components ranging 0-255. Insights: The RGB macro can be used to compute a valid color value for use while in hi/truecolor modes. It returns a number in the format &hRRGGBB, where RR, GG and BB equals the values passed to this function, in hexadecimal format. Internally it's defined as: #define RGB(r,g,b) ((cint(r) shl 16) or (cint(g) shl 8) or cint(b)) Example: See PUT example. Differences from QB: Macro new in FB. See also: RGBA, COLOR. +------+---------------------------------------------------------------------- | RGBA | +------+ Macro to compute valid color value for hi/truecolor modes. Syntax: RGBA(red,green,blue,alpha) Argument: Description: red,green, Red, green, blue and alpha components ranging 0-255. blue,alpha Insights: The RGBA macro works exactly like the RGB one, but also allows to specify an alpha component, for use in 32bpp modes. Internally it's defined as: #define RGBA(r,g,b,a) ((cint(a) shl 24) or (cint(r) shl 16) or _ (cint(g) shl 8) or cint(b)) Example: none Differences from QB: Macro new in FB. See also: RGB, COLOR. +--------+-------------------------------------------------------------------- | SCREEN | +--------+ Statement to set current gfx mode. Syntax: SCREEN mode[,[depth][,[num_pages][,[flags][,refresh_rate]]]] Argument: Description: mode Gfx mode number, see below. depth Color depth in bits per pixel. If you omit this argument, the default depth for given mode is set. num_pages Number of pages, see below. Default if omitted is 1. flags Mode options, see below. Default if omitted is 0. refresh_rate Requested refresh rate in Hz. Default if omitted is 0, which lets gfxlib to pick up a working refresh rate automatically. Insights: The SCREEN statement sets the current gfx mode. Available modes list follows: Mode 1: 320x200 in CGA emulation. 40x25 text format, 8x8 character size. 16 background colors and one of four sets of foreground colors set by the COLOR statement. Mode 2: 640x200 in CGA emulation. 80x25 text format, 8x8 character size. 16 colors assigned to any of 2 attributes. Mode 7: 320x200 in EGA emulation. 40x25 text format, 8x8 character size. 16 colors assigned to any of 16 attributes. Mode 8: 640x200 80x25 text format, 8x8 character size. 16 colors assigned to any of 16 attributes. Mode 9: 640x350 80x25 or 80x43 text format, 8x14 or 8x8 character size. 64 colors assigned to any of 16 attributes. Mode 11: 640x480 80x30 or 80x60 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 2 attributes. Mode 12: 640x480 80x30 or 80x60 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 16 attributes. Mode 13: 320x200 40x25 text format, 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 14: 320x240 40x30 text format, 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 15: 400x300 50x37 text format, 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 16: 512x384 64x24 or 64x48 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 17: 640x400 80x25 or 80x50 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 18: 640x480 80x30 or 80x60 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 19: 800x600 100x37 or 80x75 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 20: 1024x768 128x48 or 128x96 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. Mode 21: 1280x1024 160x64 or 160x128 text format, 8x16 or 8x8 character size. Assignment of up to 256K colors to any of 256 attributes. For modes 14 and up, the depth parameter changes the color depth to the specified new one; if depth is not specified, these modes run in 8bpp. For modes 13 and below, depth has no effect. If you need custom resolutions, have a look at the SCREENRES statement. The num_pages parameter specifies the number of "pages" supported by the video mode: a page is either the visible screen or an offscreen buffer the same size of the screen. You can show a page while working on another one; see the SCREENSET statement for details. You can request any number of pages for any video mode; if you omit num_pages, 1 will be assumed, and only the visible page (number 0) will be available. The flags parameter can be an OR combination of the following values: Value: Option description: &h1 Request fullscreen mode &h2 Request OpenGL mode &h10 Request stencil buffer for when in OpenGL mode &h20 Request accumulation buffer for when in OpenGL mode Depending on if the fullscreen flag is set or not, SCREEN will try to set the specified video mode in fullscreen or windowed mode, respectively. Note that the system may not be able to fulfill this request, fallbacking on a working alternative. If the OpenGL flag is set, gfxlib will enter OpenGL mode: all primitives drawing functions will have no effect and the screen will not be automatically updated for you. Basically in OpenGL mode you're just left alone with a working OpenGL window, and your OpenGL code should handle all rendering. When a frame is ready, you can request a page flip using the FLIP command, which has this special behaviour while in OpenGL mode. The stencil buffer flag has effect only when in OpenGL mode, and if set it requests the OpenGL context to have a stencil buffer. Similarly, the accumulation flag also only works when an OpenGL mode has been requested, and requests an accumulation buffer for it. The refresh_rate parameter allows to specify a desired refresh rate for the gfx mode to be set; this is just an hint to gfxlib, which will try to fullfil the request. It is not guaranteed that the mode will have specified refresh rate; if gfxlib can't set it, it'll fall back on the first working rate. If you omit this parameter or pass 0 to it, gfxlib will automatically detect and use the first working refresh rate for specified mode. Gfxlib will try its best to fulfill your gfx mode requests, but if everything fails no mode will be set and execution will resume from the statement next to the SCREEN call. So you should take particular care about checking if SCREEN is successful; a way to do this is to test the return value of the SCREENPTR function, have a look at it for details. Another way is just to check for errors with ON ERROR; SCREEN will cause an illegal function call error on failure. To find out which video modes are supported by the host system, you can use the SCREENLIST function. Once a gfx mode has been set, you can toggle fullscreen and windowed mode at any time by pressing ALT-ENTER, providing the system supports it. While in windowed mode, clicking on the window close button will return CHR$(255)+"X" to INKEY$, while clicking on the maximize window button will switch to fullscreen mode if possible. The system mouse cursor is displayed by default; you can hide it at any time using the SETMOUSE statement. A successful SCREEN call sets currently visible and working pages both to page number 0, resets the palette to the specified mode one (see appendix B), resets the clipping region to the size of the screen, disables custom coordinates mappings, moves the gfx cursor to the center of the screen, moves the text cursor to the top-left corner of the screen and sets foreground and background colors to bright white and black respectively. Example: ' Sets fullscreen 640x480 with 32bpp color depth and 4 pages SCREEN 18, 32, 4, 1 IF NOT SCREENPTR THEN PRINT "Error setting video mode!" END END IF Differences from QB: Parameters differ, FB version allows additional modes and color depths, and any number of pages in any mode. See also: SCREENRES, SCREENLOCK, SCREENUNLOCK, SCREENPTR, SCREENSET, SCREENCOPY, SCREENINFO, SETMOUSE, PALETTE. +------------+---------------------------------------------------------------- | SCREENCOPY | +------------+ Statement to copy the contents of a graphical page into another graphical page, or to swap OpenGL buffers. Syntax: SCREENCOPY [from_page][,to_page] Argument: Description: from_page Page to copy from. If you omit this argument, the current work page is assumed. to_page Page to copy to. If you omit this argument, the currently visible page is assumed. Insights: You can use this function to add a double buffer to your graphics. Any SCREEN mode supports this function; you must supply valid page numbers otherwise SCREENCOPY will have no effect. If a viewport has been set with the VIEW statement, only the viewport area is copied, otherwise the whole page. If in OpenGL mode, calling this function will result in a hardware page flip, causing the rendered frame to be displayed; in this case the from_page and to_page parameters have no meaning and are always not used. This function has two aliases: FLIP and PCOPY. Example: See SCREENSET example. Differences from QB: Function new in FB: works like the QB PCOPY statement, but works for any gfx mode, providing you requested enough pages. See also: SCREEN, SCREENSET. +------------+---------------------------------------------------------------- | SCREENINFO | +------------+ Statement to retrieve information about current video mode. Syntax: SCREENINFO [w][,[h][,[depth][,[bpp][,[pitch][,[rate][,driver]]]]] Argument: Description: w,h Width and height of gfx mode in pixels. depth Color depth in bits per pixel. bpp Bytes per pixel. pitch Bytes per row. rate Refresh rate in Hertz. driver Name of the gfx driver being used. Insights: SCREENINFO can be used to retrieve informations on the current gfx mode; if no mode is set when this statement is called, informations on the system desktop will be returned. Driver name is the internal gfxlib driver name being used (for example: "GDI", "DirectX", "X11"). If querying the desktop, the empty string will be stored in driver. If SCREENINFO fails to query for a specific information, 0 will be stored in the corresponding variable passed by reference. Example: SCREEN 15, 32 ' Obtain info about current mode SCREENINFO w, h, depth,,,refresh,driver_name$ PRINT STR$(w) + "x" + STR$(h) + "x" + STR$(depth); IF (refresh > 0) THEN PRINT " @ " + STR$(refresh) + " Hz"; END IF PRINT " using " + driver_name$ + " driver" SLEEP ' Quit gfx mode and obtain info about desktop SCREEN 0 SCREENINFO w, h, depth PRINT "Desktop running at " + STR$(w) + "x" + STR$(h) + "x" + STR$(depth); Differences from QB: Function new in FB. See also: SCREEN, SCREENLIST. +------------+---------------------------------------------------------------- | SCREENLIST | +------------+ Function to fetch supported video modes. Syntax: SCREENLIST ([depth]) Insights: The SCREENLIST function can be used to find out at runtime which fullscreen video modes are available on the host machine. This works like the DIR$ function: you first have to call this function once requesting the list of supported resolutions for a given color depth (supported depths are 8, 15, 16, 24 and 32); this will return the first supported resolution for the request, encoded in an integer result such that the screen width and height are stored in the high and low word respectively. Next, continue calling SCREENLIST without parameters to get the next supported resolutions, until 0 is returned. Resolutions are returned from lowest to highest supported ones. Also, it is safe to call this function at any time. Example: DIM AS INTEGER mode, w, h '' Find which 8bit resolutions are supported mode = SCREENLIST(8) WHILE (mode) w = HIWORD(mode) h = LOWORD(mode) PRINT STR$(w) + "x" + STR$(h) mode = SCREENLIST WEND Differences from QB: Function new in FB. See also: SCREEN, SCREENRES. +------------+---------------------------------------------------------------- | SCREENLOCK | +------------+ Statement to lock work page framebuffer. Syntax: SCREENLOCK Insights: The SCREENLOCK function locks the current work page framebuffer for direct memory access. Once the page is locked, the screen contents stop being updated automatically until you unlock the page with the SCREENUNLOCK statement. While the work page is locked, you can read/write its memory freely; you must call SCREENUNLOCK when you are done. It is strongly recommended that you hold a page locked for a time as short as possible; and you should also note that you are not supposed to call SCREENLOCK if a lock has not been unlocked first, even though nested calls will simply have no effects. If the work page is the same as the visible page, any modifications to the page memory while locked will not become visible until SCREENUNLOCK is called. Example: See SCREENPTR example. Differences from QB: Function new in FB. See also: SCREEN, SCREENUNLOCK, SCREENPTR. +-----------+----------------------------------------------------------------- | SCREENPTR | +-----------+ Function to retrieve a pointer to current work page framebuffer memory. Syntax: SCREENPTR Insights: The SCREENPTR function returns a pointer to the current work page framebuffer memory, or NULL (0) if no gfx mode is set. It can be used either to test if a call to SCREEN is successful, either to do read/write operations directly to the work page memory, providing the page is first locked and later unlocked via the SCREENLOCK and SCREENUNLOCK statements. The pointer returned by SCREENPTR is only valid after a successful call to SCREEN, and is invalidated by subsequent calls to SCREEN. Example: ' Set good old 320x200 in 8bpp mode ' No pages specified so we have one work page = visible page SCREEN 13 ' We're in an 8bpp mode, so a BYTE PTR is needed for framebuffer access DIM framebuffer AS BYTE PTR framebuffer = SCREENPTR ' We need to lock current work page before access is possible SCREENLOCK ' Plot a white pixel at coordinates 160,100 on the work page POKE framebuffer + (100 * 320) + 160, 15 ' Unlock work page so our change is made visible SCREENUNLOCK SLEEP Differences from QB: Function new in FB. See also: SCREEN, SCREENLOCK, SCREENUNLOCK. +-----------+----------------------------------------------------------------- | SCREENRES | +-----------+ Statement to set a custom resolution gfx mode. Syntax: SCREENRES width,height[,[depth][,[num_pages][,[flags][,refresh_rate]]]] Argument: Description: width Width of the new gfx mode in pixels. height Height of the new gfx mode in pixels. depth Same as for the SCREEN statement, look at it for details. num_pages Same as for the SCREEN statement, look at it for details. flags Same as for the SCREEN statement, look at it for details. refresh_rate Same as for the SCREEN statement, look at it for details. Insights: SCREENRES works exactly like SCREEN, but allows to set custom resolutions. Example: none Differences from QB: Function new in FB. See also: SCREEN. +-----------+----------------------------------------------------------------- | SCREENSET | +-----------+ Statement to set current work and visible pages. Syntax: SCREENSET [work_page][,visible_page] Argument: Description: work_page New work page number. visible_page New visible page number. Insights: SCREENSET allows to set the current working page and the current visible page. Page numbers can range 0-(num_pages - 1), where num_pages is the number of pages set by the most recent call to the SCREEN statement. You can use this function to achieve page-flipping or double-buffering. If you omit work_page but not visible_page, only visible page is changed. If you omit visible_page but not work_page, only work page is changed. If you omit both arguments, both work page and visible page are reset to page 0. Example: ' Set good old 320x200 in 8bpp mode, but with 2 pages SCREEN 13, ,2 COLOR ,15 DIM x AS INTEGER x = -40 ' Let's work on page 1 while we display page 0 SCREENSET 1, 0 DO CLS LINE (x, 80)-(x + 39, 119), 4, BF x = x + 1 IF (x > 319) THEN x = -40 ' Wait for vertical sync WAIT &h3DA, 8 ' Copy work page to visible page SCREENCOPY LOOP WHILE INKEY$ = "" Differences from QB: Function new in FB. See also: SCREEN, SCREENCOPY. +------------+---------------------------------------------------------------- | SCREENSYNC | +------------+ Statement to wait for screen vertical blank. Syntax: SCREENSYNC Insights: SCREENSYNC waits for the screen vertical blank to occur, then returns control to the caller program. Example: none Differences from QB: Function new in FB. See also: SCREEN, WAIT. +--------------+-------------------------------------------------------------- | SCREENUNLOCK | +--------------+ Statement to unlock work page framebuffer. Syntax: SCREENUNLOCK [start_line][,end_line] Argument: Description: start_line Optional argument specifying first screen line to be updated. If you omit this argument, top screen line is assumed. end_line Optional argument specifying last screen line to be updated. If you omit this argument, bottom screen line is assumed. Insights: SCREENUNLOCK unlocks the current work page assuming it was previously locked by calling SCREENLOCK. This function lets the system restart updating the screen regularly, and when called produces the immediate update of the screen region marked by the given start and end lines. When no lock is held, you can no longer directly access the work page framebuffer via SCREENPTR. Example: See SCREENPTR example. Differences from QB: Function new in FB. See also: SCREEN, SCREENLOCK, SCREENPTR. +----------+------------------------------------------------------------------ | SETMOUSE | +----------+ Statement to position and show/hide the system mouse cursor. Syntax: SETMOUSE [x][,[y][,cursor]] Argument: Description: x,y Screen coordinates of the new mouse cursor position. cursor Pass 0 to hide the cursor, or 1 to show it. Insights: This statement is useful to set the current system mouse cursor position, and to hide or show it. The cursor is shown by default when you call SCREEN. Example: none Differences from QB: Function new in FB. See also: GETMOUSE. +------+---------------------------------------------------------------------- | VIEW | +------+ Statement to define new physical coordinates mapping and clipping region. Syntax: VIEW [[SCREEN] (x1,y1)-(x2,y2) [,[color][,border]]] Argument: Description: SCREEN When specified, any x,y coordinate will be relative to the top-left corner of the screen, and not to the left-top corner of the viewport. x1,y1,x2,y2 Coordinates of the top-left and bottom-right corners of the new viewport. color Color with which to clear the new viewport; if you omit this argument, the viewport will not be cleared. border Color of the border box surrounding the new viewport. If you omit this argument, no border box will be drawn. Insights: Use this statement to set a new clipping region, also known as viewport. The new viewport will override the previous one, if any; if the SCREEN argument is omitted, all future coordinates specifications will be relative to the top-left corner of the new viewport, instead of relative to the top-left corner of the screen. Any graphical primitive will be affected by the new viewport, and drawing outside specified region will produce no effect. If color is specified, in the same format as the one supported by COLOR, the new viewport is cleared with it; if border is specified, also in COLOR format, a box using border as color will be drawn surrounding given region. If all arguments are omitted, the viewport is reset to the screen mode size. Example: none Differences from QB: none See also: SCREEN, WINDOW. +------+---------------------------------------------------------------------- | WAIT | +------+ Statement for DOS port data waiting emulation. Syntax: WAIT port,and_expr[,xor_expr] Argument: Description: port DOS port number onto wait data for. and_expr Integer expression to be ANDed with data from the port; if the result of this operation is not 0, the statement returns. xor_expr Integer expression to be XORed with data from the port, before passing it to and_expr. If you omit this argument, 0 is assumed. Insights: The only port number WAIT supports is &h3DA, for vertical blank syncing. You should only call WAIT this way: WAIT &h3DA, 8 Any other combination of port, and_expr and xor_expr will have no effect. This function is supported for backwards QB compatibility only; it is recommended that you use SCREENSYNC in your programs if you want to wait for the vertical blank. Example: See SCREENSET example. Differences from QB: This is just an emulation of the QB WAIT statement, and only supports port number &h3DA. See also: SCREENSYNC, INP, OUT. +--------+-------------------------------------------------------------------- | WINDOW | +--------+ Statement to define new view coordinates mapping for current viewport. Syntax: WINDOW [[SCREEN] (x1,y1)-(x2,y2)] Argument: Description: SCREEN Optional argument specifying y coordinates increase from top to bottom. x1,y1,x2,y2 New floating point values corresponding to the opposite corners of the current viewport. Insights: WINDOW is used to define a new coordinates system. (x1,y1) and (x2,y2) are the new coordinates to be mapped to the opposite corners of the current viewport; all future coordinates passed to gfx primitive statements will be affected by this new mapping. If SCREEN is omitted, the new coordinates system will be cartesian, that is, with y coordinates increasing from bottom to top. Call WINDOW with no argument to disable the coordinates transformation. Example: none Differences from QB: none See also: SCREEN, VIEW. +-------------+--------------------------------------------------------------- | WINDOWTITLE | +-------------+ Statement to set the program window title. Syntax: WINDOWTITLE stringexpr Argument: Description: stringexpr String to be assigned as new window title. Insights: This statement is useful to change the program window title. The new title set will become active immediately if the program already runs in windowed mode, otherwise will become the new title for any window produced by subsequent calls to the SCREEN statement. If you never call this function before setting a new windowed mode via SCREEN, the program window will have your executable file name without extension as title by default. Example: WINDOWTITLE "FreeBASIC example program" SCREEN 15 SLEEP Differences from QB: Function new in FB. See also: SCREEN. ============================================================================== Appendix A: DOS keyboard scancodes ============================================================================== Here follows a list of hardware keyboard scancodes accepted by the MULTIKEY function. These are equal to DOS scancodes, and are guaranteed to be always recognized on all platforms. These constants are also defined in the fbgfx.bi include file you can use in your programs. #define SC_ESCAPE &h01 #define SC_1 &h02 #define SC_2 &h03 #define SC_3 &h04 #define SC_4 &h05 #define SC_5 &h06 #define SC_6 &h07 #define SC_7 &h08 #define SC_8 &h09 #define SC_9 &h0A #define SC_0 &h0B #define SC_MINUS &h0C #define SC_EQUALS &h0D #define SC_BACKSPACE &h0E #define SC_TAB &h0F #define SC_Q &h10 #define SC_W &h11 #define SC_E &h12 #define SC_R &h13 #define SC_T &h14 #define SC_Y &h15 #define SC_U &h16 #define SC_I &h17 #define SC_O &h18 #define SC_P &h19 #define SC_LEFTBRACKET &h1A #define SC_RIGHTBRACKET &h1B #define SC_ENTER &h1C #define SC_CONTROL &h1D #define SC_A &h1E #define SC_S &h1F #define SC_D &h20 #define SC_F &h21 #define SC_G &h22 #define SC_H &h23 #define SC_J &h24 #define SC_K &h25 #define SC_L &h26 #define SC_SEMICOLON &h27 #define SC_QUOTE &h28 #define SC_TILDE &h29 #define SC_LSHIFT &h2A #define SC_BACKSLASH &h2B #define SC_Z &h2C #define SC_X &h2D #define SC_C &h2E #define SC_V &h2F #define SC_B &h30 #define SC_N &h31 #define SC_M &h32 #define SC_COMMA &h33 #define SC_PERIOD &h34 #define SC_SLASH &h35 #define SC_RSHIFT &h36 #define SC_MULTIPLY &h37 #define SC_ALT &h38 #define SC_SPACE &h39 #define SC_CAPSLOCK &h3A #define SC_F1 &h3B #define SC_F2 &h3C #define SC_F3 &h3D #define SC_F4 &h3E #define SC_F5 &h3F #define SC_F6 &h40 #define SC_F7 &h41 #define SC_F8 &h42 #define SC_F9 &h43 #define SC_F10 &h44 #define SC_NUMLOCK &h45 #define SC_SCROLLLOCK &h46 #define SC_HOME &h47 #define SC_UP &h48 #define SC_PAGEUP &h49 #define SC_LEFT &h4B #define SC_RIGHT &h4D #define SC_PLUS &h4E #define SC_END &h4F #define SC_DOWN &h50 #define SC_PAGEDOWN &h51 #define SC_INSERT &h52 #define SC_DELETE &h53 #define SC_F11 &h57 #define SC_F12 &h58 ' Extra scancodes not compatible with DOS scancodes #define SC_LWIN &h7D #define SC_RWIN &h7E #define SC_MENU &h7F ============================================================================== Appendix B: Default palettes ============================================================================== These are the default palettes you get when SCREEN is called: Index: Color: Mode 1: 0 Black 1 Cyan 2 Magenta 3 White Modes 2,10, and 11: 0 Black 1 White Mode 7, 8, 9 0 Black 12 and first 1 Blue 16 colors of 2 Green mode 13 and up: 3 Cyan 4 Red 5 Pink 6 Yellow 7 Grey 8 Dark grey 9 Bright blue 10 Bright green 11 Bright cyan 12 Bright red 13 Bright pink 14 Bright yellow 15 White ============================================================================== Appendix C: Internal pixel formats ============================================================================== Internally, gfxlib always uses one of 3 pixel formats: indexed 1 byte per pixel, direct color 2 bytes per pixel and direct color 4 bytes per pixel. Here's a table to determine the pixel format depending on current color depth: Depth: Pixel format: 1 1 byte per pixel, indexed, index ranging 0-1. 2 1 byte per pixel, indexed, index ranging 0-3. 4 1 byte per pixel, indexed, index ranging 0-15. 8 1 byte per pixel, indexed, index ranging 0-255. 15,16 2 bytes per pixel, direct color, RRRRRGGGGGGBBBBB. 24,32 4 bytes per pixel, direct color, AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB. As you can see, 15 and 16bpp modes internally have the same 16bpp format. The same can be said for 24 and 32bpp modes, both using the 32bpp format. This internal format is platform independent. The pages memory will have pixels data set up in one of the 3 formats just specified, so keep this in mind when accessing it via SCREENPTR; the same applies to data in GET and PUT arrays. Mask color for GET/PUT arrays is then encoded this way: Depth: Mask color value: 1,2,4,8 0 15,16 &hF81F 24,32 &hFF00FF Indexed modes always use color index 0 for transparency, while direct color modes use bright pink. ============================================================================== Appendix D: About speed and size ============================================================================== About speed: internally gfxlib uses normal system memory as pages memory. All your read/writes on the page buffers (including direct writes via SCREENPTR) will be done in system memory. On Win32 and Linux, a separated thread does the screen updates as needed, running at the refresh rate speed; only dirty lines are updated. This thread also does color conversion if needed. While this may sound as an overhead in fullscreen modes, it is necessary for windowed modes; to keep the lib slim and simple, the same method has been used also in fullscreen, at the cost of a tiny speed penalty due to the memory copy. MMX is used whenever possible all over gfxlib though, so the lib is still pretty fast. About size: one of the goals of gfxlib was to be independent of external libs. Well, the goal has been achieved: the lib has its own tiny drivers (10-15 KB each) and does not depend on anything else. Of course your EXEs will have to include also other code at least for gfx initialization, fonts data, support for all color depths, default palettes and some other stuff. All this means if you use gfxlib routines your EXE size will increase in size from 40K up to about 90K, depending on the functionalities your program uses (fbc will link in just what you use). But your EXEs will be standalone. Of course by standalone it doesn't mean it has no dependencies at all, but just dependencies to system libraries you can assume to be always available. Here's a list of the additional dependencies your EXEs will have when using gfxlib: Win32: user32.dll gdi32.dll (ddraw.dll, dinput.dll and opengl32.dll only loaded at runtime) Linux: libX11 libXpm libXext libXrender libXrandr libpthread (libGL only loaded at runtime) ============================================================================== Appendix E: Internal drivers ============================================================================== As previously stated, gfxlib features its own tiny drivers to work on various systems. Here is the list of drivers: Win32: DirectX This driver is based on DirectDraw and DirectInput; it'll work on any system that has already at least DirectX 3.0 installed. Windows 98 is the minimum OS requirement; if you have Windows 95 this is not guaranteed to work. The required DirectX DLLs are loaded at execution time, so your EXE will not depend on them, being able to also run on systems where DX is not installed (this driver will fail to initialize there). Supports windowed and fullscreen modes. GDI Basic Windows GDI driver; slower than DirectX, yet guaranteed to always work. This is a fallback driver for when DX is not installed. Supports windowed mode only. OpenGL OpenGL driver; likely to be hardware accelerated on every system, it always works. Supports windowed and fullscreen modes. Linux: X11 Raw Xlib based driver; it always works, providing an X11 server is reachable (at least XFree86 4.3.0 or Xorg required). If your program runs locally, it uses the Xshm extension to provide faster framebuffer access via shared memory. For fullscreen mode switching, the Xrandr extension is used (your X11 gfx driver must support resolution switching, and your program needs to be executed locally, otherwise fullscreen will not work). OpenGL OpenGL driver; likely to be hardware accelerated on every system, it works as long as your X server is configured for OpenGL support. Supports windowed and fullscreen modes, but for fullscreen to work the same conditions as those requested by the raw X11 driver need to be satisfied. DOS: VGA Supported on any VGA-compatible adapter, this driver provides 256- color modes 320x200, 320x100, 256x256, 160x120, and 80x80. ModeX Supported on any VGA-compatible adapter, this driver provides 256- color modes 320x240. It is based on the classic Mode X tweak by Michael Abrash. gfxlib will always choose the best driver for your system when a new video mode is set via SCREEN. To override driver selection, you can set the FBGFX environmental variable to the name of the driver you want to be tried first: on Win32 for example you could do: set FBGFX=gdi This way gfxlib will first try to initialize a driver named "GDI"; if given driver fails or cannot be found, gfxlib will fallback on the usual automatic driver selection path. ============================================================================== Appendix F: Hints ============================================================================== - Avoid double buffering whenever possible; gfxlib already uses a double buffering system internally to keep the screen updated, so using your own double buffer will just mean an additional (unneeded) screen copy, thus a slowdown. Use the provided page flipping capabilities exported via the SCREENSET statement; see the MULTIKEY example provided in this doc, or see the fbgfx_flame.bas source in your FreeBASIC/examples/gfx directory. - Other than normal arrays, GET and PUT support pointers as pixel data holder; the following code will work: TYPE FB_IMAGE FIELD = 1 width AS USHORT height AS USHORT imageData(64000) AS UBYTE END TYPE DIM udt AS FB_IMAGE DIM udt_ptr AS FB_IMAGE PTR DIM array(16001) AS INTEGER DIM array_ptr AS INTEGER PTR udt_ptr = @udt array_ptr = @array(0) SCREEN 13 ' These are all equivalent to each other GET (0,0)-(319,199), array GET (0,0)-(319,199), array(0) GET (0,0)-(319,199), @array(0) GET (0,0)-(319,199), array_ptr GET (0,0)-(319,199), @array_ptr[0] ' These are also all equivalent to each other GET (0,0)-(319,199), @udt GET (0,0)-(319,199), udt_ptr GET (0,0)-(319,199), @udt_ptr[0] Here we used GET for the example, but the concept applies to PUT as well. - All gfx primitives can work on GET/PUT buffers. This means you can have any number of offscreen surfaces of any size where to draw your stuff, and blit your buffers later onto the screen: DIM buffer(9602) AS USHORT DIM sprite(1028) AS UBYTE SCREEN 13 ' Since buffer is supposed to be a GET/PUT buffer, here we manually ' set it up so its first 4 bytes are the usual GET/PUT buffer header. buffer(0) = 160 SHL 3 ' Width * 8 buffer(1) = 120 ' Height CIRCLE buffer, (16,16), 15, 12,,, 1, F GET buffer, (0,0)-(31,31), sprite PSET sprite, (16,16), 15 LINE buffer, (0,0)-(159,119), 2, B PUT buffer, (50,50), sprite, PSET PUT (80,40),buffer, PSET An easier way to create a GET/PUT buffer is to use the IMAGECREATE function: this will automatically allocate and set up the image buffer for you. The above example would become: DIM buffer AS ANY PTR DIM sprite AS ANY PTR SCREEN 13 buffer = IMAGECREATE(160, 120) sprite = IMAGECREATE(32, 32) CIRCLE buffer, (16,16), 15, 12,,, 1, F GET buffer, (0,0)-(31,31), sprite PSET sprite, (16,16), 15 LINE buffer, (0,0)-(159,119), 2, B PUT buffer, (50,50), sprite, PSET PUT (80,40),buffer, PSET IMAGEDESTROY buffer IMAGEDESTROY sprite When drawing onto a buffer, coordinates are affected by the most recent call to WINDOW, but VIEW has no effect; clipping is set to the whole buffer area. Of course the optional target buffer parameter passed to all gfx primitives can be an array as well as a pointer, as in the case of GET/PUT pixel data holders. - You can enhance the PRINT functionality by using a custom routine that uses the internal predefined gfx fonts. The following snippet defines a new GfxPrint function that allows to draw transparent text by specifying the location in pixel coordinates, supports clipping and also allows to print text on GET/PUT buffers: DECLARE SUB GfxPrint( BYREF text AS STRING, _ BYVAL x AS INTEGER, BYVAL y AS INTEGER, _ BYVAL col AS INTEGER, BYVAL buffer AS ANY PTR = 0 ) TYPE fb_FontType w AS INTEGER ' Width in pixels h AS INTEGER ' Height in pixels data AS UBYTE PTR END TYPE ' Uncomment the internal gfx font you want to use EXTERN fb_FontData ALIAS "fb_font_8x8" AS fb_FontType 'EXTERN fb_FontData ALIAS "fb_font_8x14" AS fb_FontType 'EXTERN fb_FontData ALIAS "fb_font_8x16" AS fb_FontType SUB GfxPrint( BYREF text AS STRING, _ BYVAL x AS INTEGER, BYVAL y AS INTEGER, _ BYVAL col AS INTEGER, BYVAL buffer AS ANY PTR = 0 ) DIM row AS INTEGER, i AS INTEGER DIM bits AS UBYTE PTR FOR i = 1 TO LEN(text) bits = fb_FontData.data + _ (ASC(MID$(text, i, 1)) * fb_FontData.h) FOR row = 0 TO fb_FontData.h-1 IF (buffer) THEN LINE buffer, (x + 7, y + row)_ -(x, y + row), col,, _ *bits SHL 8 ELSE LINE (x + 7, y + row)-(x, y + row),_ col,, *bits SHL 8 END IF bits += 1 NEXT row x += 8 NEXT i END SUB SCREEN 13 GfxPrint "Hello world!", 112, 96, 15 SLEEP Pay attention when using the internal fonts data; gfxlib stores all fonts and palettes internally in a LZW compressed format to save binary space in your EXEs, and decompresses the data on the first call to SCREEN. If you do not call SCREEN in your programs, accessing the internal palettes and fonts data will return garbage. - Gfxlib internally stores default fonts and palettes data in a LZW compressed format, decompressing it once on the first call to SCREEN. The tiny LZW codec used is not visible to the user programs not to clutter namespace, and as it's not really in the scope of gfxlib to provide data compressing facilities. Nonetheless, as it's there, you can access it by declaring prototypes of the encode and decode routines, pointing to the correct implementation inside gfxlib. Here's an example: DECLARE FUNCTION LZW_Encode ALIAS "fb_hEncode" ( _ BYVAL in_buffer AS ANY PTR, _ BYVAL in_size AS INTEGER, _ BYVAL out_buffer AS ANY PTR, _ BYREF out_size AS INTEGER _ ) AS INTEGER DECLARE FUNCTION LZW_Decode ALIAS "fb_hDecode" ( _ BYVAL in_buffer AS ANY PTR, _ BYVAL in_size AS INTEGER, _ BYVAL out_buffer AS ANY PTR, _ BYREF out_size AS INTEGER _ ) AS INTEGER DIM src_buffer(100000) AS UBYTE DIM src_size AS INTEGER DIM dest_buffer(100000) AS UBYTE DIM dest_size AS INTEGER '' Cannot work if our program doesn't link with gfxlib SCREEN 15 src_size = 0 OPEN "gfxlib.txt" FOR BINARY AS #1 WHILE NOT EOF(1) GET #1,, src_buffer(src_size) src_size += 1 WEND CLOSE #1 PRINT "Data size before compression:", src_size GOSUB ShowData dest_size = 100000 PRINT "Compressing..."; LZW_Encode @src_buffer(0), src_size, @dest_buffer(0), dest_size PRINT "done." PRINT "Data size after compression:", dest_size PRINT src_size = 100000 PRINT "Decompressing..."; LZW_Decode @dest_buffer(0), dest_size, @src_buffer(0), src_size PRINT "done." PRINT "Data size before decompression:", src_size GOSUB ShowData SLEEP END ShowData: DIM i AS INTEGER PRINT "Contents: "; FOR i = 3 TO 36: PRINT CHR$(src_buffer(i)); : NEXT PRINT " [...]" RETURN - Creating an OpenGL texture out of a GET/PUT buffer is easy; here's a small snippet that does it: #DEFINE TEX_MASKED &h1 #DEFINE TEX_MIPMAP &h2 #DEFINE TEX_NOFILTER &h4 #DEFINE TEX_HASALPHA &h8 FUNCTION CreateTexture( BYVAL buffer AS ANY PTR, BYVAL flags AS INTEGER _ = 0 ) AS GLuint REDIM dat(0) AS UBYTE DIM p AS UINTEGER PTR, s AS USHORT PTR DIM AS INTEGER w, h, x, y, col DIM tex AS GLuint DIM AS GLenum format, minfilter, magfilter CreateTexture = 0 s = buffer w = s[0] SHR 3 h = s[1] IF( (w < 64) OR (h < 64) ) THEN EXIT FUNCTION END IF IF( (w AND (w-1)) OR (h AND (h-1)) ) THEN '' Width/height not powers of 2 EXIT FUNCTION END IF REDIM dat(w * h * 4) AS UBYTE p = @dat(0) glGenTextures 1, @tex glBindTexture GL_TEXTURE_2D, tex FOR y = h-1 TO 0 STEP -1 FOR x = 0 TO w-1 col = POINT(x, y, buffer) '' Swap R and B so we can use the GL_RGBA texture format col = RGBA(col AND &hFF, _ (col SHR 8) AND &hFF, _ (col SHR 16) AND &hFF, _ col SHR 24) IF( flags AND TEX_HASALPHA ) THEN *p = col ELSE IF( (flags AND TEX_MASKED) AND _ (col = &hFF00FF) ) THEN *p = 0 ELSE *p = col OR &hFF000000 END IF END IF p += 4 NEXT x NEXT y IF( flags AND ( TEX_MASKED OR TEX_HASALPHA ) ) THEN format = GL_RGBA ELSE format = GL_RGB END IF IF( flags AND TEX_NOFILTER ) THEN magfilter = GL_NEAREST ELSE magfilter = GL_LINEAR END IF IF( flags AND TEX_MIPMAP ) THEN gluBuild2DMipmaps GL_TEXTURE_2D, format, w, h, GL_RGBA, _ GL_UNSIGNED_BYTE, @dat(0) IF( flags AND TEX_NOFILTER ) THEN minfilter = GL_NEAREST_MIPMAP_NEAREST ELSE minfilter = GL_LINEAR_MIPMAP_LINEAR END IF ELSE glTexImage2D GL_TEXTURE_2D, 0, format, w, h, 0, GL_RGBA, _ GL_UNSIGNED_BYTE, @dat(0) minfilter = magfilter END IF glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter CreateTexture = tex END FUNCTION