C Programming Tips

On this page I want to publish some tips for programming in GNU C (either gcc and egcs). For now these tips are:

Please select one of these topics in the navigation bar.

Remark: I found out that some functionality provided on this page doesn't work at every version of Linux, it's distribution or specific library. I cannot guaranty that these programs always compile and run correctly. Use them on your own risk.

Top of page

Console Works

SVGALIB graphics

SVGALIB sprites


Console Works

If you ever wrote programs in Borland C at the MS-DOS or OS/2 platform, you had the functions gotoxy() and _textattr(). The first function positioned the cursor at the specified position. The second function changed the attributes of the text. These functions only worked at the console. Another useful function was clrscr() for cleaning the screen.


In gcc or egcs, no such functions are available. This is because of the nature of the Linux operating system. Every I/O is based on streams and files. The console can be considered as a special file. There is a library, ncurses, which provides special console functions like cursor positioning and text colors.


But if your terminal supports ANSI escape codes, you might use some simple printf() functions for cursor positioning, text colors, and cleaning up.


Take a look at this screenshot for an example:


console colour demo


Again, this only works if your terminal supports ANSI Escape codes completely. I have to admit I didn't wrote the gotoxy() and clrscr() code myself. Unfortunately I cannot find the websites where I found them so I cannot give the credits to whom they belong. If I find out I'll update this page.


Follow the next link for viewing and downloading my conio.h for gcc / egcs.


Top of page

Console Works

SVGALIB graphics

SVGALIB sprites

Using simple graphics in SVGALIB programs

A while ago I discovered SVGALIB for writing graphical programs at the Linux console. SVGALIB provides some basic functionality for reading and drawing pixels in SVGA graphical screens. Generally, SVGALIB allows you to use low-level functions of your graphics board. SVGALIB comes with many Linux distributions, e.g. Suse and RedHat.


I wrote some routines which made using SVGALIB a lot easier for me. They give you some basis functions when using graphics: plotting pixels, drawing lines and shapes like circles, rectangles and triangles. These shapes can be the outlines or filled in solid or with a user defined pattern. Special functions for displaying text and numbers and reading keys are available.


Normally, the origin of your drawing screen is the upper left corner of the screen. In my routines it is possible to redefine the origin to any point of the display for easy drawing of mathematical functions (you don't have to use an offset for negative values anymore).


Let's take a look at the functions in graphics.h:


Function

Description

void block(int mode, int xlo, int ylo, int xrb, int yrb)

Draws a rectangle. If mode==0 only the outlines are drawn. The other parameters are the lower left corner and the upper right corner of the rectangle.

void circle(int mode, int x, int y, int r)

Draws a circle. If mode==0 only the outlines are drawn. The other parameters present the center of the circle and the radius.

void drawline(int x1, int y1, int x2, int y2)

Draws a line between x1, y1 and x2,y2

int gread(char *buffer, int x, int y, int hsize, int vsize, int n, int col, int bgcol)

Reads a string from the keyboard. The keyboard has to be initialized with init_keyboard. The position of the text, it's size and color have to be specified. The background color is necessary for deleting characters.

void grmod(int mouse)

Initializes the 640x480x16 graphical mode. If the mouse functions will be used the parameter MOUSE has to be passed, else use NOMOUSE.

void gwindow(int xlo, int ylo, int xrb, int yrb)

Defines a graphical, logical window. Only within this window pixels are plotted. This works only with the functions from this toolkit. All native SVGALIB functions ignore this window.

void gwinoff(void)

Disables the graphical, logical window. Pixels are plotted all over the screen.

void gwrite(char *s, int x, int y, int hsize, int vsize)

Plots a text string at x,y. The size of the characters is passed as parameters.

void init_keyboard(void)

Initializes the keyboard, i.e. put it in non-canonical mode and reduce the input buffer to 1 character. So, getchar() reads exactly one keystroke, without an enter.

int kbhit(void)

After initializing the keyboard with the previous function you can use kbhit for checking if a key is pressed. The function returns 0 if no key pressed. Read the key with getchar().

int loadfont(char *f)

Loads a font which is used by gwrite. Returns 0 if no error occurred.

void origin(int x, int y)

Moves the logical origin to a new position.

int paint(int x, int y, int border, int nr)

This function fills an area with a user defined pattern or a solid color. The area is limited with the `border' color. If nr==-1 paint will use the current color for painting.

int paintdef(int nr, char *pattern)

Defines a pattern for painting. Each pattern is 256 bytes in size, 16 rows of 16 pixels. Each pixel is represented by a single byte. *pattern points to the pattern in memory.

void plotpix(int x, int y)

Plots a single pixel.

void printdec(int v, int n, int x, int y, int hsize, int vsize)

Prints the decimal value of the parameter `v', n digits at x,y. Hsize and vsize are the size of the digits. This function uses gwrite for drawing the digits.

void restore_keyboard(void)

Restores the keyboard to normal state after placing it in non-canonical mode with init_keyboard.

void scroll(char *s, int scrolllen, char c, int x, int y, int hsize, int vsize, int col, int bgcol)

Makes a message scrolling from right to left. Scrolling ends by pressing a key.

void setlinestyle(int style)

Defines the appearance of a line, use it for drawing dotted lines. Not used by native SVGALIB functions. Some predefined line styles are: SOLID_LINE, DOTTED_LINE, CENTER_LINE and DASHED_LINE.

void triangle(int mode, int x1, int y2, int x2, int y2, int x3, int y3)

Draws a triangle. If mode==0 only the outlines are drawn.

void txmod(void)

Restores the textmode.


Some functions come in pairs: after using grmod() you have to use txmod(), also after using init_keyboard() an restore_keyboard() has to be issued. Otherwise you leave your system in an undefined state after ending a program. If your program crashes SVGALIB takes care of restoring the text mode, if possible.


I noticed that the screen is not always cleared after using txmod(). This is a problem of SVGALIB, as txmod() only calls vga_mode(TEXT). A known limitation of this toolkit is that it only can be used in 320*200*16 and 640*320*16 color modi.


Top of page

Console Works

SVGALIB graphics

SVGALIB sprites


Using sprites and mouse pointers in SVGALIB programs

Another set of functions for SVGALIB is sprites.h. In this include file you have the extension for using sprites and sprite administration by simple means. You don't have to take care where a sprite is, if it hits another sprite etc. You just have to define a sprite, put it somewhere on the screen and move it.


A very special sprite is the mouse cursor sprite. SVGALIB provides some low-level mouse support, but lacks the mouse pointer on the screen. These functions only add a visual mouse pointer, and it's cooperation with other sprites. All initialization has to be done with the native SVGALIB functions! All functions for normal sprites also apply to the mouse pointer. In fact, the mouse pointer is a normal sprite. Its default sprite number is 0, but you might change it by assigning another value to the integer MOUSECUR. Use this if you need different mouse pointers (e.g. a normal one and one for waiting while busy).


If you're using sprites graphics.h is automatically includes, as sprites.h uses some functions and global variables of graphics.h.


Here are the sprite functions from sprites.h:

Function

Description

int mouse_hotspot(int x, int y)

Defines the hotspot of the mouse pointer. By default this is the upper left corner of the mouse sprite. X and Y are a value between 0 and 31.

int mouse_move(void)

Moves the mouse to it's new position. This position is retrieved by SVGALIB functions.

int mouse_off(void)

Removes the mouse pointer from the screen.

int mouse_on(void)

Places the mouse pointer on the screen.

int sprite_def(int sprite_nr, char *sprdata)

Defines a sprite. The first parameter is the number of the sprite, the second parameter is a pointer to a block of 1024 bytes, containing the sprite data. Each byte represents a single pixel. Use pixel color 255 as a transparent pixel. The mouse pointer is also defined with this function.

int sprite_hit(int sprite1, int sprite2)

Checks if two sprites hit. Use MOUSECUR as sprite2 when checking if a sprite is hit by the mouse.

int sprite_init(int nr_of_sprites)

Initializes the sprite administration. For each sprite 2048 bytes of memory and two integers are used.

int sprite_move(int sprite_nr, int new_x, int new_y)

Moves a sprite to its new position. The screen data at it's old location will be restored.

int sprite_put(int sprite_nr, int x, int y)

Draws a sprite on the screen without saving screen data and not updating sprite administration.

int sprite_set(int sprite_nr, int x, int y)

Places a sprite on the screen. Saves the screen data under the sprite and updates the sprite administration.

int sprite_unset(int sprite_nr)

Removes a sprite from the screen, restoring previous screen data and updating sprite administration.


sprite_init() returns 0 if the allocation of memory for sprite administration succeeded. Otherwise it returns 1 which is mostly due to insufficient memory. All other functions return a status code. The bits in this status code have the following definitions:


+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+
  |   |   |   |   |   |   |   |
  |   |   |   |   |   |   |   +---- mouse button 1 (sprite_hit only)
  |   |   |   |   |   |   +-------- mouse button 2 (sprite_hit only)
  |   |   |   |   |   +------------ mouse button 3 (sprite_hit only)
  |   |   |   |   +---------------- illegal parameter
  |   |   |   +-------------------- no sprites available
  |   |   +------------------------ illegal sprite number 1
  |   +---------------------------- illegal sprite number 2
  +-------------------------------- sprite 1 hits sprite 2 or mouse

Top of page

Console Works

SVGALIB graphics

SVGALIB sprites




Last update: august 21, 2000