// EZ-VGA graphics library for DJGPP // Header file v1.4 // All code (c) Copyright Matthew Bentley 1996-1998 // EZ-VGA graphics library (c) Copyright Matthew Bentley 1996-1998. // ******* Include files needed for EZVGA : ******* #include // For screen access : #include // For screen interrupts : #include // For file functions : #include // For 'outportb' functions : // ********************************************************************* // ******* Required variables for EZVGA : ******* // ********************************************************************* // The screen access pointer - cannot be used under djgpp until 'vgainit()' // is used : unsigned char *VIDEO; // Register struct for use in interrupt generation : __dpmi_regs regs; // Generate Sin look-up table (Required for the 'circle' function) : const unsigned int sintable[91] = { 0,175,349,523,698, 872,1045,1219,1392, 1564,1736,1908,2079, 2250,2419,2588,2756, 2924,3090,3256,3420, 3584,3746,3907,4067, 4226,4384,4540,4695, 4848,5000,5150,5299, 5446,5592,5736,5878, 6018,6157,6293,6428, 6561,6691,6820,6947, 7071,7193,7314,7431, 7547,7660,7771,7880, 7986,8090,8192,8290, 8387,8480,8572,8660, 8746,8829,8910,8988, 9063,9135,9205,9272, 9336,9397,9455,9511, 9563,9613,9659,9703, 9744,9781,9816,9848, 9877,9903,9925,9945, 9962,9976,9986,9994, 9998,10000 }; // Generate default borders (Used for clipping) : unsigned int Xmin = 0, Xmax = 319; unsigned char Ymin = 0, Ymax = 199; // Enum definitions: enum fill {EMPTY, FILLED}; enum offset {SCREEN, ARRAY = 3}; enum mousestate {ON = 0x0001, OFF = 0x0002}; // ******* End of required values for EZVGA ******* // *************************************************** // ******* EZVGA functions : ******* // *************************************************** // ******* Graphics functions : ******* // To clear the 'regs' register structure : // Syntax is "clearregs();" void clearregs() { regs.d.edi = 0; regs.d.esi = 0; regs.d.ebp = 0; regs.d.res = 0; regs.d.ebx = 0; regs.d.edx = 0; regs.d.ecx = 0; regs.d.eax = 0; regs.x.di = 0; regs.x.di_hi = 0; regs.x.si = 0; regs.x.si_hi = 0; regs.x.bp = 0; regs.x.bp_hi = 0; regs.x.res = 0; regs.x.res_hi = 0; regs.x.bx = 0; regs.x.bx_hi = 0; regs.x.dx = 0; regs.x.dx_hi = 0; regs.x.cx = 0; regs.x.cx_hi = 0; regs.x.ax = 0; regs.x.ax_hi = 0; regs.x.flags = 0; regs.x.es = 0; regs.x.ds = 0; regs.x.fs = 0; regs.x.gs = 0; regs.x.ip = 0; regs.x.cs = 0; regs.x.sp = 0; regs.x.ss = 0; unsigned char counter; for (counter = 0; counter != 4; counter++) { regs.h.edi[counter] = 0; regs.h.esi[counter] = 0; regs.h.ebp[counter] = 0; regs.h.res[counter] = 0; } regs.h.bl = 0; regs.h.bh = 0; regs.h.ebx_b2 = 0; regs.h.ebx_b3 = 0; regs.h.dl = 0; regs.h.dh = 0; regs.h.edx_b2 = 0; regs.h.edx_b3 = 0; regs.h.cl = 0; regs.h.ch = 0; regs.h.ecx_b2 = 0; regs.h.ecx_b3 = 0; regs.h.al = 0; regs.h.ah = 0; regs.h.eax_b2 = 0; regs.h.eax_b3 = 0; } // To put the computer in 320x200 - 256 colours (Standard VGA) graphics mode: // Syntax is "vgainit();" void vgainit() { // Clear registers : clearregs(); regs.x.ax = 0x13; __dpmi_int(0x10, ®s); // Enable the nearptr technique in DJGPP for direct screen access : __djgpp_nearptr_enable(); VIDEO = (unsigned char *)0xA0000 + __djgpp_conventional_base; } // To change the screen back to text mode & clean up : // Syntax is "vgaexit();" void vgaexit() { clearregs(); regs.x.ax = 0x03; __dpmi_int(0x10, ®s); // *** Kill near pointers *** : __djgpp_nearptr_disable(); } // To change the borders to which video output will be clipped : // Syntax is "setborders (minimum_x, minimum_y, maximum_x, maximum_y);" void setborders (unsigned int minx, unsigned int miny, unsigned int maxx, unsigned int maxy) { Xmin = minx; Ymin = miny; Xmax = maxx; Ymax = maxy; if (Xmin > 319) Xmin = 319; if (Ymin > 199) Ymin = 199; if (Xmax > 319) Xmax = 319; if (Ymax > 199) Ymax = 199; if (Xmin > Xmax) { // Swap Xmin & Xmax, using xs as the spare : unsigned int xs; xs = Xmin; Xmin = Xmax; Xmax = xs; } if (Ymin > Ymax) { // Swap Ymin & Ymax, using ys as the spare : unsigned char ys; ys = Ymin; Ymin = Ymax; Ymax = ys; } } // To set the palette of any certain colour : // Syntax is "setpal (colour, red value, green value, blue value);" void setpal(const unsigned char col, const unsigned char r, const unsigned char g, const unsigned char b) { outportb (0x03C8,col); outportb (0x03C9,r); outportb (0x03C9,g); outportb (0x03C9,b); } // To set the whole 256 colour palette from a 768-byte array : // (Palette array contains bytes of red, green and blue values for each // colour) // Syntax is "setallpals (palette_array);" void setallpals(const unsigned char *palarray) { unsigned int palnum; for (palnum = 0; palnum != 256; palnum++) { outportb (0x03C8, palnum); outportb (0x03C9, palarray[(palnum << 1) + palnum]); outportb (0x03C9, palarray[(palnum << 1) + palnum + 1]); outportb (0x03C9, palarray[(palnum << 1) + palnum + 2]); } } // To fill the screen with a certain colour : // Syntax is "cls (colour);" void cls(const unsigned char col) { unsigned int cx; unsigned char cy; for (cy = Ymin; cy != Ymax + 1; cy++) for (cx = Xmin; cx != Xmax + 1; cx++) VIDEO[(cy << 8) + (cy << 6) + cx] = col; } // To put a pixel on the screen of colour 0-255 at co-ordinates x, y : // Syntax = "putpix(x, y, colour);" inline void putpix(const int xp, const int yp, const unsigned char col) { if (xp >= Xmin && yp >= Ymin && xp <= Xmax && yp <= Ymax) VIDEO[(yp << 8) + (yp <<6) + xp] = col; } // To read the colour of a pixel on the screen at co-ordinates x, y : // Off screen co-ordinates will be returned as 0. // Syntax = "colour = getpix(x, y);" unsigned char getpix(const int xp, const int yp) { if (xp < 0 || yp < 0 || xp > 319 || yp > 199) return 0; return VIDEO[(yp << 8) + (yp << 6) + xp]; } // To make a line, hollow box or filled box : // Syntax = "line (x1, y1, x2, y2, colour);" void line(int x1, int y1, int x2, int y2, const unsigned char col) { char sgndistx1, sgndisty1, sgndistx2, sgndisty2; int counter2, distx, disty, absdistx, absdisty; unsigned int counter; distx = x2 - x1; disty = y2 - y1; // Return the sign of distx: if (distx < 0) sgndistx1 = -1; else if(distx > 0) sgndistx1 = 1; else sgndistx1 = 0; // Return the sign of disty: if (disty < 0) sgndisty1 = -1; else if (disty > 0) sgndisty1 = 1; else sgndisty1 = 0; // Get the absolute value of distx: absdistx = distx; if (absdistx < 0) absdistx *= -1; // Get the absolute value of disty: absdisty = disty; if (absdisty < 0) absdisty *= -1; if (absdistx <= absdisty) { sgndistx2 = 0; sgndisty2 = sgndisty1; // Swap absdistx & absdisty, using counter2 as the spare: counter2 = absdistx; absdistx = absdisty; absdisty = counter2; } else { sgndistx2 = sgndistx1; sgndisty2 = 0; } counter2 = absdistx >> 1; for (counter = 0; counter != absdistx; counter++) { if (x1 >= Xmin && y1 >= Ymin && x1 <= Xmax && y1 <= Ymax) VIDEO[(y1 << 8)+(y1 << 6) + x1] = col; counter2 += absdisty; if (counter2 >= absdistx) { counter2 -= absdistx; x1 += sgndistx1; y1 += sgndisty1; } else { x1 += sgndistx2; y1 += sgndisty2; } } } // To make an empty or filled box : // Syntax : box(x1, y1, x2, y2, colour, EMPTY or FILLED (in upper-case)) void box (int x1, int y1, int x2, int y2, const unsigned char col, const fill boxtype) { unsigned int x3; if (x2 < x1) { // Swap x1 & x2, using x3 as the spare : x3 = x1; x1 = x2; x2 = x3; } if (y2 < y1) { // Swap y1 & y2, using x3 as the spare : x3 = y1; y1 = y2; y2 = x3; } // For hollow box : if (boxtype == EMPTY) { for (x3 = x1; x3 != x2 + 1; x3++) { if (x3 >= Xmin && y1 >= Ymin && y1 <= Ymax && x3 <= Xmax) VIDEO[(y1 << 8) + (y1 << 6) + x3] = col; if (x3 >= Xmin && y2 >= Ymin && y2 <= Ymax && x3 <= Xmax) VIDEO[(y2 << 8) + (y2 << 6) + x3] = col; } for (; y1 != y2 + 1; y1++) { if (x1 >= Xmin && y1 >= Ymin && y1 <= Ymax && x1 <= Xmax) VIDEO[(y1 << 8) + (y1 << 6) + x1] = col; if (x2 >= Xmin && y1 >= Ymin && y1 <= Ymax && x2 <= Xmax) VIDEO[(y1 << 8) + (y1 << 6) + x2] = col; } } // For filled box : if (boxtype == FILLED) { for (; y1 != y2 + 1; y1++) for (x3 = x1; x3 != x2 + 1; x3++) if (x3 >= Xmin && y1 >= Ymin && y1 <= Ymax && x3 <= Xmax) VIDEO[(y1 << 8) + (y1 << 6) + x3] = col; } } // To draw a circle on the screen at origin co-ordinates x, y, // with a colour of 0-255, and a radius of 'radius' : // Syntax = "circle(x, y, radius, colour);" void circle(const int xc, const int yc, const unsigned long int radius, const unsigned char col) { unsigned char counter; // Initialize offset values : unsigned int xset, yset; // Initialize new values : int x1n, y1n, x2n, y2n; // Initialize old values with the 1st points of the circle : int x1 = (int)(xc + (10000UL * radius + 5000) / 10000); int y1 = yc; int x2 = (int)(xc - (10000UL * radius + 5000) / 10000); int y2 = yc; // Fill the vertical-top gaps : xset = (unsigned int)((1000UL * radius + 5000) / 10000); yset = (unsigned int)((9998UL * radius + 5000) / 11800); x1n = xc - xset + 1; y1n = yc - yset; x2n = xc + xset; y2n = yc + yset; line(x1n, y1n, x2n, y1n, col); line(x1n, y2n, x2n, y2n, col); // Start loop at second point of the circle : for (counter = 0; counter != 90; counter++) { xset = (unsigned int)(((unsigned long int)(sintable[-(counter - 90)]) * radius + 5000) / 10000); yset = (unsigned int)(((unsigned long int)(sintable[counter]) * radius + 5000) / 11800); x1n = xc + xset; y1n = yc + yset; x2n = xc - xset; y2n = yc - yset; // Draw lines between new values & old values : line(x1, y1, x1n, y1n, col); line(x2, y1, x2n, y1n, col); line(x2, y2, x2n, y2n, col); line(x1, y2, x1n, y2n, col); // Update old values : x1 = x1n; y1 = y1n; x2 = x2n; y2 = y2n; } } // To draw an ellipse on the screen at origin co-ordinates x, y, // with a colour of 0-255, a horizontal radius of 'x_radius' and a // vertical radius of y_radius : // Syntax = "ellipse(x, y, x_radius, y_radius, colour);" void ellipse(const int xc, const int yc, const unsigned long int xradius, const unsigned long int yradius, const unsigned char col) { unsigned char counter; // Initialize offset values : unsigned int xset, yset; // Initialize new values : int x1n, y1n, x2n, y2n; // Initialize old values with the 1st points of the circle : int x1 = (int)(xc + (10000UL * xradius + 5000) / 10000); int y1 = yc; int x2 = (int)(xc - (10000UL * xradius + 5000) / 10000); int y2 = yc; // Fill the vertical-top gaps : xset = (unsigned int)((1000UL * xradius + 5000) / 10000); yset = (unsigned int)((9998UL * yradius + 5000) / 11800); x1n = xc - xset + 1; y1n = yc - yset; x2n = xc + xset; y2n = yc + yset; line(x1n, y1n, x2n, y1n, col); line(x1n, y2n, x2n, y2n, col); // Start loop at second point of the ellipse : for (counter = 0; counter != 90; counter++) { xset = (unsigned int)(((unsigned long int)(sintable[-(counter - 90)]) * xradius + 5000) / 10000); yset = (unsigned int)(((unsigned long int)(sintable[counter]) * yradius + 5000) / 11800); x1n = xc + xset; y1n = yc + yset; x2n = xc - xset; y2n = yc - yset; // Draw lines between new values & old values : line(x1, y1, x1n, y1n, col); line(x2, y1, x2n, y1n, col); line(x2, y2, x2n, y2n, col); line(x1, y2, x1n, y2n, col); // Update old values : x1 = x1n; y1 = y1n; x2 = x2n; y2 = y2n; } } // To get a square of graphics from the screen : // Syntax is "getpic (x1, y1, x2, y2, array_name);" void getpic(int x1, int y1, int x2, int y2, unsigned char *arpointer) { unsigned int xsize, xg; if (x1 < Xmin) x1 = Xmin; if (y1 < Ymin) y1 = Ymin; if (x1 > Xmax) x1 = Xmax; if (y1 > Ymax) y1 = Ymax; if (x2 < Xmin) x2 = Xmin; if (y2 < Ymin) y2 = Ymin; if (x2 > Xmax) x2 = Xmax; if (y2 > Ymax) y2 = Ymax; if (x2 < x1) { // Swap x1 & x2, using xg as the spare : xg = x1; x1 = x2; x2 = xg; } if (y2 < y1) { // Swap y1 & y2, using xg as the spare : xg = y1; y1 = y2; y2 = xg; } // Record the picture length & height: xsize = x2 - x1; if (xsize > 255) { *arpointer = 255; arpointer++; *arpointer = xsize - 255; arpointer++; } else { *arpointer = 0; arpointer++; *arpointer = xsize; arpointer++; } *arpointer = y2 - y1; arpointer++; // Ecrement x2 & y2 by one so that the != y2 or != x2 statements // stop -after- the -true- values of y2 and x2: x2++; y2++; for (; y1 != y2; y1++) { for (xg = x1; xg != x2; xg++) { *arpointer = VIDEO[(y1 << 8) + (y1 << 6) + xg]; arpointer++; } } } // To put a square of picture onto the screen : // Syntax is "putpic(x_coordinate, y_coordinate, array_name);" void putpic(const int x1, int y1, const unsigned char *arpointer) { int xp = x1; // Ecrement x2 & y2 by one so that the != y2 or != x2 statements // stop -after- the -true- values of y2 and x2: int x2 = arpointer[0] + arpointer[1] + x1 + 1; int y2 = arpointer[2] + y1 + 1; arpointer += 3; for (; y1 != y2; y1++) { for (xp = x1; xp != x2; xp++) { if (xp >= Xmin && xp <= Xmax && y1 >= Ymin && y1 <= Ymax) VIDEO[(y1 << 8) + (y1 << 6) + xp] = *arpointer; arpointer++; } } } // To put a square of picture on the screen, ignoring any one colour : // Syntax is "putsprite(x_coordinate, y_coordinate, array_name, // ignored_colour);" void putsprite(const int x1, int y1, const unsigned char *arpointer, unsigned char colour) { int xp = x1; // Ecrement x2 & y2 by one so that the != y2 or != x2 statements // stop -after- the -true- values of y2 and x2: int x2 = arpointer[0] + arpointer[1] + x1 + 1; int y2 = arpointer[2] + y1 + 1; arpointer += 3; for (; y1 != y2; y1++) { for (xp = x1; xp != x2; xp++) { if (xp >= Xmin && xp <= Xmax && y1 >= Ymin && y1 <= Ymax && *arpointer != colour) VIDEO[(y1 << 8) + (y1 << 6) + xp] = *arpointer; arpointer++; } } } // ******* File loading functions : ******* // To load a file of raw binary data : // Syntax is "loadraw ("filename", array_name);" // (A returned -1 means the file was not found.) char loadraw(const char *filename, unsigned char *arrayname) { FILE *graphfile; unsigned int length; graphfile = fopen(filename, "rb"); if (!graphfile) return -1; fseek(graphfile, -1L, SEEK_END); length = (unsigned int)ftell(graphfile); fseek(graphfile, 0, 0); fread(&arrayname[0], length, 1, graphfile); fclose (graphfile); return 0; } // To save information from an array as a raw binary data file: // Syntax is "saveraw("filename", array_name, array_size);" // (A returned -1 means the file could not be opened.) char saveraw(const char *filename, const unsigned char *arrayname, const unsigned int size) { FILE *graphfile; graphfile = fopen(filename, "wb"); if (!graphfile) return -1; fwrite(&arrayname[0], size, 1, graphfile); fclose(graphfile); return 0; } // To load a file of .BLD format : // Syntax is "loadbld ("filename", array_name);" // (To load a bld file direct to the screen, type video in // the 'array_name' option.) // (A returned -1 means the file was not found.) char loadbld(const char *filename, unsigned char *arrayname) { FILE *graphfile; unsigned int length; graphfile = fopen(filename, "rb"); if (!graphfile) return -1; fseek(graphfile, -1L, SEEK_END); length = (unsigned int) (ftell(graphfile) - 6); fseek (graphfile, 7, 0); fread (&arrayname[0], length, 1, graphfile); fclose (graphfile); return 0; } // To save an array of length ????? as a .BLD file : // Syntax is "savebld("filename", array_name, array_size);". // (Handy hint : To save a bld file from the screen, put 'video' in the // 'array_name' option and '64000U' in the 'array_size' option.) // (A returned -1 means the file could not be opened.) char savebld(const char *filename, const unsigned char *arrayname, const unsigned int size) { FILE *bldfile; bldfile = fopen(filename, "wb"); if (!bldfile) return -1; fputc(253, bldfile); fputc(146, bldfile); fputc(89, bldfile); fputc(4, bldfile); fputc(0, bldfile); fputc(0, bldfile); fputc(250, bldfile); fwrite(&arrayname[0], size, 1, bldfile); fclose(bldfile); return 0; } // To load a file of .PCX format : // Syntax is "loadpcx("filename", array or screen, arrayname, palette_array);" // (To load the pcx picture into an array, which you can later put onto the // screen using the 'putpic' command, put the array's name in the 'arrayname' option. // To load the pcx file direct to the screen, put 'VIDEO' in the 'arrayname' // option.) // (A returned -1 means the file was not found.) loadpcx(const char *filename, unsigned char *arpointer, unsigned char *pals) { unsigned int xsize, ysize, counter; // Open the file : FILE *graphfile; graphfile = fopen(filename, "rb"); if (!graphfile) return -1; // Create a header structure for the pcx file : typedef struct { unsigned char manufacturer; unsigned char version; unsigned char encoding; unsigned char bitperpix; short int xtop; short int ytop; short int xsiz; short int ysiz; short int hres; short int vres; short int egacolour[24]; char reserved; unsigned char planes; short int bytesperline; short int paltype; char unused[58]; } PCX_HEADER; PCX_HEADER header; fread (&header, 128, 1, graphfile); // Test to see that the file is a genuine 256 colour PCX : if (header.version != 5 || header.bitperpix != 8 || header.encoding != 1) { fclose (graphfile); return -2; } // Load the palette from the PCX file & check genuine PCX : fseek(graphfile, -769L, SEEK_END); counter = fgetc(graphfile); if (counter != 0x0C) { fclose(graphfile); return -2; } fread (&pals[0], 768, 1, graphfile); for (counter = 0; counter != 768; counter++) { pals[counter] >>= 2; } fseek(graphfile, 128, SEEK_SET); // Find width & length of PCX : xsize = header.xsiz; ysize = header.ysiz; if (xsize > 319) { xsize = 319; } if (ysize > 199) { ysize = 199; } if (arpointer != VIDEO) { if (xsize > 255) { *arpointer = 255; arpointer++; *arpointer = xsize - 255; arpointer++; } else { *arpointer = 0; arpointer++; *arpointer = xsize; arpointer++; } *arpointer = ysize; arpointer++; } unsigned char byte; // If the PCX file is larger than 320x200 then 'squash it' : if (header.xsiz > 319 || header.ysiz > 199) { unsigned char runlength; unsigned long int x; unsigned long int y; // Find graphics 'squash' factor : unsigned int xfac = (unsigned int) (((float)319 / (float)(header.xsiz)) * 10000); unsigned int yfac = (unsigned int) (((float)200 / (float)(header.ysiz)) * 10000); for (y = 0; y <= 1990000L; y += yfac) { for (x = 0; x <= 3190000L; x += xfac) { byte = fgetc(graphfile); // Check for a run : if ((byte & 0xc0) == 0xc0) { // Get run length : runlength = byte & 0x3f; // Get run colour : byte = fgetc(graphfile); for (; runlength != 0; runlength--) { *arpointer = byte; arpointer++; x += xfac; } x -= xfac; } // If no run is detected : else { *arpointer = byte; arpointer++; } } } } // If picture is less than or equal to 320x200 : else { unsigned char *runlength; unsigned char *totalbytes; totalbytes = arpointer + (header.ysiz + 1) * (header.xsiz + 1) + 1; for (; arpointer != totalbytes; arpointer++) { byte = fgetc(graphfile); // Check for a run : if ((byte & 0xc0) == 0xc0) { runlength = arpointer + (byte & 0x3f); // Use 'byte' as the colour buffer : byte = fgetc(graphfile); for (; arpointer != runlength; arpointer++) *arpointer = byte; arpointer--; } // If no run detected : else *arpointer = byte; } } fclose (graphfile); return 0; } // To save a .PCX file from an array or the screen : // Syntax is "savepcx (filename, array or screen, array_name, pal_array);". // (To the entire screen into a pcx, put 'video' in the 'array_name' option. // To save the pcx from an array, get the image from the screen into an array // using the "getpic" and put the name of the array which holds the image // into the 'array_name' option.) // (The function returns a -1 if the file could not be opened.) char savepcx(const char *filename, const unsigned char *arpointer, const unsigned char *palarray) { unsigned char palcopy[769]; unsigned char byte, runlength; unsigned int position; const unsigned char *totalbytes; // Open the file : FILE *graphfile; graphfile = fopen(filename, "wb"); if (!graphfile) return -1; // Create a header structure for the pcx file : typedef struct { unsigned char manufacturer; unsigned char version; unsigned char encoding; unsigned char bitperpix; short int xtop; short int ytop; short int xsiz; short int ysiz; short int hres; short int vres; short int egacolour[24]; char reserved; unsigned char planes; short int bytesperline; short int paltype; char unused[58]; } PCX_HEADER; PCX_HEADER header; header.manufacturer = 10; header.version = 5; header.encoding = 1; header.bitperpix = 8; header.xtop = 0; header.ytop = 0; header.hres = 320; header.vres = 200; header.reserved = 0; header.planes = 1; header.paltype = 2; for (position = 0; position != 25; position++) header.egacolour[position] = 0; for (position = 0; position != 59; position++) header.unused[position] = 0; // Set the pcx width & lengths : if (arpointer != VIDEO) { header.xsiz = arpointer[0] + arpointer[1]; header.ysiz = arpointer[2]; header.bytesperline = arpointer[0] + arpointer[1] + 1; arpointer += 3; } else { header.xsiz = 319; header.ysiz = 199; header.bytesperline = 320; } fwrite(&header, 128, 1, graphfile); totalbytes = arpointer + (header.xsiz + 1) * (header.ysiz + 1) + 1; for (; arpointer != totalbytes; arpointer++) { byte = *arpointer; arpointer++; // Check for a run : if (byte == *arpointer && arpointer != totalbytes) { runlength = 3; arpointer++; while (byte == *arpointer && arpointer != totalbytes) { runlength++; arpointer++; if (runlength == 64) break; } runlength += 191; fputc(runlength, graphfile); fputc(byte, graphfile); } // If no run was detected : else { if (byte >= 192) fputc(193, graphfile); fputc(byte, graphfile); } arpointer--; } fputc(0x0C, graphfile); for (position = 0; position != 769; position++) palcopy[position] = palarray[position] << 2; fwrite(&palcopy[0], 768, 1, graphfile); fclose(graphfile); return 0; } // ******* Mouse functions : ******* // To check that a mouse driver is present and initialize it: // Syntax is "status = mouseinit();". // (Returns 0 if no mouse present, 1 if mouse present.) unsigned char mouseinit() { clearregs(); regs.x.ax = 0x00; __dpmi_int(0x33, ®s); if (regs.x.ax == 0xFFFF) return 1; else return 0; } // To turn the mouse cursor on or off : // Syntax is "mousecursor(on or off);". void mousecursor(mousestate status) { clearregs(); regs.x.ax = status; __dpmi_int(0x33, ®s); } // To get the current mouse position : // Syntax is "getmousepos(X_mouse, Y_mouse);". void getmousepos(int &mousex, int &mousey) { clearregs(); regs.x.ax = 0x03; __dpmi_int(0x33, ®s); mousex = regs.x.cx; mousey = regs.x.dx; mousex >>= 1; } // To set the mouse position on the screen : // Syntax is "setmousepos(X_mouse, Y_mouse);". void setmousepos(int mousex, int mousey) { mousex <<= 1; clearregs(); regs.x.ax = 0x0004; regs.x.cx = mousex; regs.x.dx = mousey; __dpmi_int(0x33, ®s); } // To get the current mouse button status : // Syntax is "status = mousebuttons();". // (Returns 0 if no buttons pushed, 1 if left button pushed, // 2 if right button pushed & 3 if both buttons pushed.) unsigned char mousebuttons() { clearregs(); regs.x.ax = 0x0003; __dpmi_int(0x33, ®s); if (regs.x.bx == 0x0001) return 1; if (regs.x.bx == 0x0002) return 2; if (regs.x.bx == 0x0003) return 3; return 0; } // To set the X & Y screen limits for the mouse : // Syntax is "setmouselimits(x_min, y_min, x_max, y_max);". void setmouselimits(int x1, int y1, int x2, int y2) { if (x2 < x1) { // Swap x1 & x2, using xs as the spare : int xs = x1; x1 = x2; x2 = xs; } if (y2 < y1) { // Swap y1 & y2, using ys as the spare : int ys = x1; y1 = y2; y2 = ys; } x1 <<= 1; x2 <<= 1; clearregs(); regs.x.ax = 7; regs.x.cx = x1; regs.x.dx = x2; __dpmi_int(0x33, ®s); regs.x.ax = 8; regs.x.cx = y1; regs.x.dx = y2; __dpmi_int(0x33, ®s); } // ******* End of EZVGA functions *******