/*==========================================================================
*
* EXAMP001.C Sunday, September 11, 1994
*
* Sample source code for The BESTLibrary v2.32. Demonstrates the use of
* the various graphics functions.
*
* Intended to give examples of:
* _16_c_need_scrn
* _16_c_need_wrst
* _16_c_save
* _16_c_show
* _16_copy
* _16_i_need
* _16_i_save
* _16_i_show
* _16_p_need
* _16_p_save
* _16_p_show
*
* Authored independently by George Vanous
* Email any comments, compliments, or suggestions to [[Email Removed]]
*
*==========================================================================*/
/* NOTE if, when you compile, you receive a linker error that states there
are two undefined symbols "EGAVGA_driver_far" and "small_font_far",
you need to perform the following steps:
1) go into your BGI subdirectory (where EGAVGA.BGI is located)
2) type BGIOBJ /F EGAVGA
3) type BGIOBJ /F LITT
4) copy the two .OBJs created (EGAVGAF.OBJ and LITTF.OBJ)into the
same subdirectory as all your libraries (usually LIB\)
5) type TLIB GRAPHICS.LIB +EGAVGAF +LITTF
this updates your GRAPHICS.LIB file to include the EGAVGA.BGI file
and the LITT.CHR font (you can do this for all your .BGI and .CHR
files)
*/
/* ------------------------------------------------------------------------ */
/* ---------------------------- INCLUDE FILES --------------------------- */
#include <alloc.h>
#include <stdlib.h>
#include <graphics.h>
#include "!bestlib.h" /* include !BESTLIB.H in compilation */
/* ------------------------------------------------------------------------ */
/* ------------------------------ CONSTANTS ----------------------------- */
#define BGCLR BLUE /* background color */
#define TEXTHEIGHT 12 /* y-height of printed text */
#define BUFFERSPACE 100 /* byte size of "buffer" */
#define DASHES printf("\n--------------------------------------------------------------------------------")
#define PRINT(x, y, text) _16_boxfill(x, y+2, textwidth(text), TEXTHEIGHT-2,\
BLACK, COPY_IMAGE); outtextxy(x, y, text); /* prints in graphics mode */
#define ERR01 "\nI require 400,000 bytes (400kb) of free memory\nBut there is only %ld bytes currently available\n\nDo you want me to continue regardless [y/N] ? "
#define MSG01 "\n\nI suggest you try removing any unnecessary TSRs (Terminate but Stay Resident\nprograms) to increase the amount of available memory.\n\n"
/* ------------------------------------------------------------------------ */
/* ------------------------- FUNCTION PROTOTYPES ------------------------ */
void animate_images(void); /* animate images */
void begin_sequence(void); /* beginning sequence */
char *color_translate(int color); /* convert color from integer to string */
/* restore the background under the text pointed to by "locations" */
void erase_text(int locations[][3], int number);
void exit_sequence(void); /* exitting sequence */
void restore_background(void); /* restore the background */
void print_image_properties(int x, int y, imagedata *image, char *image_name,
char *image_command, int locations[][3]); /* print image properties */
void save_background(void); /* draw and save background */
void save_images(void); /* draw and save images */
void show_images(void); /* show images onscreen */
char *t_or_f(int boolean); /* converts a number into "TRUE" or "FALSE" */
/* ------------------------------------------------------------------------ */
/* ------------------------- GLOBAL DEFINITIONS ------------------------- */
/* The following three definition are required by TheBESTLibrary to be
present, even if they are not all used. If they are not present, the
compiler will produce a "linker error". */
asciiscan key; /* global structure "key" */
cursordata cursor; /* global structure "cursor" */
mousedata msdata; /* global structure "msdata" */
int oldmode; /* old video mode */
byte oldcurx, oldcury; /* old cursor coordinates */
char *buffer; /* general-purpose text buffer space */
char message[81]; /* 80 bytes + 1 byte for the NULL-terminating
character is sufficient to hold the longest message */
imagedata *bgscrn[4], /* storage area for the background */
*image_c[4], /* define four compress images */
*image_i[2], /* define two plane images */
*image_p[2]; /* define two pixel images */
/* ------------------------------------------------------------------------ */
/*----------------------------------------------------------------------------
* MAIN SUBROUTINE OF EXAMPLE SOURCE CODE 001
*/
void main(void)
{
begin_sequence(); /* perform the begin sequence */
save_background(); /* draw and save background */
save_images(); /* draw and save the images */
show_images(); /* show the images onscreen */
exit(0); /* executes the procedure "exit_sequence()" because of the line */
/* "atexit(exit_sequence)" in procedure "begin_sequence" */
}
/*----------------------------------------------------------------------------
* Animate the images.
*/
void animate_images(void)
{
/* restore the background under the right three images on the first row */
_16_restore_bg(image_c[1]->x, image_c[1]->y,
image_c[1]->length, image_c[1]->height, bgscrn);
_16_restore_bg(image_c[2]->x, image_c[2]->y,
image_c[2]->length, image_c[2]->height, bgscrn);
_16_restore_bg(image_c[3]->x, image_c[3]->y,
image_c[3]->length, image_c[3]->height, bgscrn);
/* now animate the image on the first row that is left */
/* restore the background under the right image on the second row */
_16_restore_bg(image_p[1]->x, image_p[1]->y,
image_p[1]->length, image_p[1]->height, bgscrn);
/* now animate the image on the second row that is left */
/* restore the background under the right image on the third row */
_16_restore_bg(image_i[1]->x, image_i[1]->y,
image_i[1]->length, image_i[1]->height, bgscrn);
/* now animate the image on the third row that is left */
}
/*----------------------------------------------------------------------------
* Beginning sequence.
*/
void begin_sequence(void)
{
int gdrv = VGA, gmod = VGAHI, error; /* help initialize the graphics mode */
char ch; /* generic character holder */
byte i, j; /* cursor position holders */
/* allocate space for a generic string buffer */
buffer = (char *) malloc(BUFFERSPACE);
/* check amount of available memory */
DASHES; /* print one line of dashes */
if (coreleft() < 400000L) {
sprintf(buffer, ERR01, coreleft());
fprintf(stderr, buffer); /* print low memory warning message */
cur_get_coord_abs(&i, &j); /* get the cursor position */
while ((ch = case_up(getchre(i, j))) != 'Y' && ch != 'N' && ch != 13) {
beep(); /* signal invalid keypress */
txt_chr_erase(i, j, 1); /* erase character */
}
if (ch != 'Y') { /* if 'Y' chosen */
fprintf(stderr, MSG01); /* print suggestion message */
exit(1); /* exit to DOS with ERRORLEVEL 1 */
} /* else continue with program */
}
fade_out(); /* fade current text screen to black */
/* initialize The BEST Library and save old video mode
* set 640x480x16 graphics mode (VGA16) and initialize the mouse (TRUE) */
oldmode = bestlib_init(VGA16, TRUE);
/* store that status of the insert, caps, num, and scroll lock */
kbd_status_save();
atexit(exit_sequence); /* define the exit procedure */
/* allocate all necessary memory */
bgscrn[0] = (imagedata *) malloc(_16_i_need(640, 204));
bgscrn[1] = (imagedata *) malloc(_16_i_need(640, 204));
bgscrn[2] = (imagedata *) malloc(_16_i_need(640, 204));
bgscrn[3] = (imagedata *) malloc(_16_i_need(640, 204));
image_c[0] = (imagedata *) malloc(_16_c_need_wrst(50, 50));
image_c[1] = (imagedata *) malloc(_16_c_need_wrst(50, 50));
image_p[0] = (imagedata *) malloc(_16_p_need(50, 50));
image_p[1] = (imagedata *) malloc(_16_p_need(50, 50));
image_i[0] = (imagedata *) malloc(_16_i_need(50, 50));
if ((image_i[1] = malloc(_16_i_need(50, 50))) == NULL) {
exit_sequence(); /* perform the exit sequence */
fprintf(stderr, "\nInsufficient free memory to continue\n");
exit(1); /* insufficient free memory -- exit to DOS with ERRORLEVEL 1 */
} /* only one "if" is necessary because if there is enough memory for
* the last allocation, there would have been enough for all of the
* previous allocations */
/* we did check to see that there was at least 400,000 bytes of
memory available, so the above memory check is unnecessary; it
is present for the purpose of example */
/* setup graphics mode */
if ((error = registerfarbgidriver(EGAVGA_driver_far)) < 0 ||
(error = registerfarbgifont(small_font_far)) < 0) {
fprintf(stderr, "\nGraphics error: %s\n", grapherrormsg(error));
exit(2); /* error registering a BGI driver -- exit to DOS */
}
initgraph(&gdrv, &gmod, "");
if ((error = graphresult()) != grOk) {
fprintf(stderr, "\nGraphics error: %s\n", grapherrormsg(error));
exit(3); /* error occurred changing to 640x480x16 video mode */
}
/* initialize mouse to 640x480x16 graphics mode
* "mousepresent" = TRUE if mouse is detected, else "mousepresent" = FALSE
ms_init(VGA16);
ms_show(); /* show mouse cursor */
*/
_16_floodallall(BGCLR); /* flood entire video memory */
settextstyle(SMALL_FONT, HORIZ_DIR, 4); /* set default output text font */
settextjustify(LEFT_TEXT, TOP_TEXT); /* define how text will be written */
}
/*----------------------------------------------------------------------------
* Return the string representation of an integer-represented color.
*
* "color" - integer representation of a color.
*
* RETURNS:
* = name of the color
* = NULL if unknown color
*/
char *color_translate(int color)
{
switch(color) {
case BLACK : return("BLACK");
case BLUE : return("BLUE");
case GREEN : return("GREEN");
case CYAN : return("CYAN");
case RED : return("RED");
case MAGENTA : return("MAGENTA");
case BROWN : return("BROWN");
case LIGHTGRAY : return("LIGHTGRAY");
case DARKGRAY : return("DARKGRAY");
case LIGHTBLUE : return("LIGHTBLUE");
case LIGHTGREEN : return("LIGHTGREEN");
case LIGHTCYAN : return("LIGHTCYAN");
case LIGHTRED : return("LIGHTRED");
case LIGHTMAGENTA: return("LIGHTMAGENTA");
case YELLOW : return("YELLOW");
case WHITE : return("WHITE");
}
return(NULL);
}
/*----------------------------------------------------------------------------
* Restore the background under the text pointed to by "locations".
*/
void erase_text(int locations[][3], int number)
{
register int i;
for (i = 0; i < number; i++)
_16_restore_bg(locations[i][0], locations[i][1]+2, locations[i][2],
TEXTHEIGHT-2, bgscrn);
}
/*----------------------------------------------------------------------------
* Exiting sequence.
*/
void exit_sequence(void)
{
closegraph(); /* shut down graphics system */
kbd_status_load();
ms_hide(); /* hide mouse cursor */
video_restore(oldmode); /* restore original video status */
exit(0); /* exit to DOS with ERRORLEVEL 0 */
}
/*----------------------------------------------------------------------------
* Restore the background.
*/
void restore_background(void)
{
/* overwrite the remaining images on the screen to restore the background */
_16_restore_bg(image_c[0]->x, image_c[0]->y,
image_c[0]->length, image_c[0]->height, bgscrn);
_16_restore_bg(image_p[0]->x, image_p[0]->y,
image_p[0]->length, image_p[0]->height, bgscrn);
_16_restore_bg(image_i[0]->x, image_i[0]->y,
image_i[0]->length, image_i[0]->height, bgscrn);
}
/*----------------------------------------------------------------------------
* Print the image properties onscreen.
*
* "x","y" - coordinates of the first line of properties
* "image" -
* "image_name" - string name of the image
* "image_cmnd" -
*/
void print_image_properties(int x, int y, imagedata *image, char *image_name,
char *image_cmnd, int locations[][3])
{
str_copy(&message[0], image_name); /* copy "image_name" */
str_copy(&message[10], "->size = %d"); /* copy "image->size" */
sprintf(buffer, message, image->size); /* define "buffer" */
PRINT(x, y, buffer); /* print "buffer" */
locations[0][0] = x, locations[0][1] = y,
locations[0][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->tclr = %s");
sprintf(buffer, message, color_translate(image->tclr));
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[1][0] = x, locations[1][1] = y,
locations[1][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->x = %d");
sprintf(buffer, message, image->x);
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[2][0] = x, locations[2][1] = y,
locations[2][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->y = %d"); /* copy "image->y" */
sprintf(buffer, message, image->y);
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[3][0] = x, locations[3][1] = y,
locations[3][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->length = %d"); /* copy "image->length" */
sprintf(buffer, message, image->length); /* define "buffer" */
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[4][0] = x, locations[4][1] = y,
locations[4][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->height = %d"); /* copy "image->height" */
sprintf(buffer, message, image->height); /* define "buffer" */
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[5][0] = x, locations[5][1] = y,
locations[5][2] = textwidth(buffer); /* save text data */
str_copy(&message[10], "->how = %s"); /* copy "image->how" */
sprintf(buffer, message, t_or_f(image->how)); /* define "buffer" */
y += TEXTHEIGHT-1; /* adjust y-coordinate */
PRINT(x, y, buffer); /* print "buffer" */
locations[6][0] = x, locations[6][1] = y,
locations[6][2] = textwidth(buffer); /* save text data */
str_copy(&message[0], image_cmnd); /* copy "image_cmnd" */
y += (TEXTHEIGHT-1)*2; /* adjust y-coordinate */
PRINT(x, y, message); /* print "message" */
locations[7][0] = x, locations[7][1] = y,
locations[7][2] = textwidth(message); /* save text data */
}
/*----------------------------------------------------------------------------
* Draw and save the background image.
*/
void save_background(void)
{
register int i, ii;
/* first, draw the border */
for (i = 0; i < 5; i++)
_16_boxoutline(i, i, MAXX - i*2, MAXY - i*2, YELLOW, COPY_IMAGE);
/* next, draw the background */
for (i = BLACK, ii = 5; i <= WHITE; i++, ii += 21)
_16_boxfill(ii, 5, 21, MAXY - 10, i, COPY_IMAGE);
for (i = YELLOW; i > BLACK; i--, ii += 21)
_16_boxfill(ii, 5, 21, MAXY - 10, i, COPY_IMAGE);
/* and finally, save the background into memory */
_16_i_save(0, 0, MAXX, 204, bgscrn[0], FALSE, TRUE);
_16_i_save(0, 204, MAXX, 204, bgscrn[1], FALSE, TRUE);
_16_i_save(0, 408, MAXX, 204, bgscrn[2], FALSE, TRUE);
_16_i_save(0, 612, MAXX, 204, bgscrn[3], FALSE, TRUE);
}
/*----------------------------------------------------------------------------
* Draw and save the images.
*/
void save_images(void)
{
/* draw a simple image offscreen (so as not to disturb the background) */
_16_boxfill(10, MAXY+10, 50, 50, LIGHTRED, COPY_IMAGE); /* 50 by 50 box */
_16_boxfill(20, MAXY+20, 30, 30, LIGHTGREEN, COPY_IMAGE);/* 30 by 30 box */
_16_boxfill(20, MAXY+30, 30, 10, BLACK, COPY_IMAGE); /* 30 by 10 box */
_16_boxfill(30, MAXY+20, 10, 30, BLACK, COPY_IMAGE); /* draw a hole */
/* allocate memory using "_16_c_need_scrn" (uses compression) */
image_c[2] = malloc(_16_c_need_scrn(10, MAXY+10, 50, 50));
image_c[3] = malloc(_16_c_need_scrn(10, MAXY+10, 50, 50));
/* save the image in the three available formats */
_16_c_save(10, MAXY+10, 50, 50, BLACK, image_c[0], FALSE, TRUE);
_16_c_save(10, MAXY+10, 50, 50, BLACK, image_c[2], FALSE, TRUE);
_16_p_save(10, MAXY+10, 50, 50, BLACK, image_p[0], FALSE, TRUE);
_16_i_save(10, MAXY+10, 50, 50, image_i[0], FALSE, TRUE);
/* make copies of the images */
_16_copy(image_c[1], image_c[0]); /* copy "c_save" image (wrst) */
_16_copy(image_c[3], image_c[2]); /* copy "c_save" image (scrn) */
_16_copy(image_p[1], image_p[0]); /* copy "p_save" image */
_16_copy(image_i[1], image_i[0]); /* copy "i_save" image */
}
/*----------------------------------------------------------------------------
* Show the images onscreen.
*/
void show_images(void)
{
int locations[9][3]; /* a two-dimensional array that will hold x, y */
/* show the images (originals and copies) */
image_c[0]->x = 10, image_c[1]->x = 100; /* set x-coordinates */
image_c[0]->y = image_c[1]->y = 150; /* set y-coordinates */
print_image_properties(10, 10, image_c[0], "image_c[0]",
"_16_c_show(10, 150, image_c[0])", locations); /* print image properties */
_16_c_show(-1, -1, image_c[0], COPY_IMAGE); /* show the original image */
_16_c_show(-1, -1, image_c[1], COPY_IMAGE); /* now show the copied image */
/* this demonstrates the usage of "-1" for the "x" value */
_16_c_show(190, 150, image_c[2], COPY_IMAGE); /* show the original image */
_16_c_show(280, 150, image_c[3], COPY_IMAGE); /* now show the copied image */
/* this demonstrates the usage of inputting the "x" value */
_16_p_show(10, 250, image_p[0], COPY_IMAGE); /* show the original image */
_16_p_show(100, 250, image_p[1], COPY_IMAGE); /* now show the copied image */
_16_i_show(10, 350, image_i[0], COPY_IMAGE); /* show the original image */
_16_i_show(100, 350, image_i[1], COPY_IMAGE); /* now show copied image */
PRINT(10, MAXY-25, message); /* print a message */
str_copy(&message[0], "images and their properties are shown -- press any \
key to return to DOS"); /* copy "image_cmnd" */
/*** the '\' character allow a string to be continued on the next line */
PRINT(10, MAXY-25, message); /* print "message" */
locations[7][0] = 10, locations[7][1] = MAXY-25,
locations[7][2] = textwidth(message); /* save text data */
getchr(); /* wait for a key press */
erase_text(locations, 9); /* restore background under text */
}
/*----------------------------------------------------------------------------
* Convert an integer into either the string "TRUE" or the string "FALSE".
*
* "boolean" - integer to check
*
* RETURNS:
* = "TRUE" if "boolean" is not equal to 0
* = "FALSE" if "boolean" is equal to 0
*/
char *t_or_f(int boolean)
{
if (boolean) return("TRUE");
else return("FALSE");
}
/*==========================================================================*/
// REALiTY