/**************************************************************************** * * SuperVGA Test Library * * Copyright (C) 1993 Kendall Bennett. * All rights reserved. * * Filename: $RCSfile: svga16mc.c $ * Version: $Revision: 1.2 $ * * Language: ANSI C * Environment: IBM PC (MSDOS) * * Description: Simple library to collect together the functions in the * SuperVGA test library for use in other C programs. The * support is reasonably low level, so you can do what you * want. * * MUST be compiled in the large model. * * $Id: svga16mc.c 1.2 1993/03/07 04:06:11 kjb Exp $ * * Revision History: * ----------------- * * $Log: svga16mc.c $ * Revision 1.2 1993/03/07 04:06:11 kjb * Bug fixes. * * Revision 1.1 1993/03/03 10:29:11 kjb * Initial revision * ****************************************************************************/ #include "svga16m.h" /*-------------------------- Internal Functions --------------------------*/ /* In svga16m.asm */ int _initSuperVGA(int driver,int chipID,int mode,int memory); int _setSuperVGAMode(void); void _getVideoInfo(int *xres,int *yres,int *bytesperline,int *maxpage); /* Global variables */ PUBLIC int _grResult; PUBLIC int maxx,maxy; PUBLIC int maxpage,bytesperline; PUBLIC bool twobanks,extendedflipping; PUBLIC int far *modeList; PUBLIC int _VESAFirst = false; PUBLIC int _ignoreSVGA = false; PRIVATE int _driver,_chipID,_memory; /*----------------------------- Implementation ----------------------------*/ PUBLIC void initSuperVGA(int *driver,int *chipID,int *memory,int *dac) /**************************************************************************** * * Function: initSuperVGA * Parameters: driver - Place to store the SuperVGA driver ID * chipID - Place to store the SuperVGA chip ID * memory - Place to store the amount of memory * dac - Place to store the Video DAC type * * Description: Detects the installed SuperVGA and initialises the library, * if the value in 'driver' is grDETECT. You can force the * library to work with any values you like, by simply * passing valid values as parameters. * ****************************************************************************/ { int i,mode; if (*driver == grDETECT) { /* Auto detect the installed graphics adapter */ MGL_detectGraph(driver,chipID,memory,dac,&mode); } modeList = MGL_availableModes(*driver,*memory); /* Check to make sure a mode is available before initialising the * SuperVGA code. */ i = 0; mode = -1; while (modeList[i] != -1) { switch(modeList[i]) { case grSVGA_320x200x16m: case grSVGA_640x350x16m: case grSVGA_640x400x16m: case grSVGA_640x480x16m: case grSVGA_800x600x16m: case grSVGA_1024x768x16m: case grSVGA_1280x1024x16m: mode = modeList[i]; /* Found a valid mode */ break; } if (mode != -1) break; i++; } if (mode != -1) { mode = _initSuperVGA(*driver,*chipID,mode,*memory); extendedflipping = (mode & 1); twobanks = (mode & 2); _driver = *driver; _chipID = *chipID; _memory = *memory; } } PUBLIC bool setSuperVGAMode(int mode) /**************************************************************************** * * Function: setSuperVGAMode * Parameters: mode - SuperVGA video mode to set. * Returns: True if the mode was set, false if not. * * Description: Attempts to set the specified video mode. This routine * assumes that the library and SuperVGA have been initialised * with the initSuperVGA() routine first. * ****************************************************************************/ { if (_initSuperVGA(_driver,_chipID,mode,_memory) == -1) return -1; if (_setSuperVGAMode()) { _getVideoInfo(&maxx,&maxy,&bytesperline,&maxpage); return true; } return false; } PUBLIC void line(int x1,int y1,int x2,int y2,long color) /**************************************************************************** * * Function: line * Parameters: x1,y1 - First endpoint of line * x2,y2 - Second endpoint of line * * Description: Scan convert a line segment using the MidPoint Digital * Differential Analyser algorithm. * ****************************************************************************/ { int d; /* Decision variable */ int dx,dy; /* Dx and Dy values for the line */ int Eincr,NEincr; /* Decision variable increments */ int yincr; /* Increment for y values */ int t; /* Counters etc. */ dx = ABS(x2 - x1); dy = ABS(y2 - y1); if (dy <= dx) { /* We have a line with a slope between -1 and 1 * * Ensure that we are always scan converting the line from left to * right to ensure that we produce the same line from P1 to P0 as the * line from P0 to P1. */ if (x2 < x1) { t = x2; x2 = x1; x1 = t; /* Swap X coordinates */ t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */ } if (y2 > y1) yincr = 1; else yincr = -1; d = 2*dy - dx; /* Initial decision variable value */ Eincr = 2*dy; /* Increment to move to E pixel */ NEincr = 2*(dy - dx); /* Increment to move to NE pixel */ putPixel(x1,y1,color); /* Draw the first point at (x1,y1) */ /* Incrementally determine the positions of the remaining pixels */ for (x1++; x1 <= x2; x1++) { if (d < 0) { d += Eincr; /* Choose the Eastern Pixel */ } else { d += NEincr; /* Choose the North Eastern Pixel */ y1 += yincr; /* (or SE pixel for dx/dy < 0!) */ } putPixel(x1,y1,color); /* Draw the point */ } } else { /* We have a line with a slope between -1 and 1 (ie: includes * vertical lines). We must swap our x and y coordinates for this. * * Ensure that we are always scan converting the line from left to * right to ensure that we produce the same line from P1 to P0 as the * line from P0 to P1. */ if (y2 < y1) { t = x2; x2 = x1; x1 = t; /* Swap X coordinates */ t = y2; y2 = y1; y1 = t; /* Swap Y coordinates */ } if (x2 > x1) yincr = 1; else yincr = -1; d = 2*dx - dy; /* Initial decision variable value */ Eincr = 2*dx; /* Increment to move to E pixel */ NEincr = 2*(dx - dy); /* Increment to move to NE pixel */ putPixel(x1,y1,color); /* Draw the first point at (x1,y1) */ /* Incrementally determine the positions of the remaining pixels */ for (y1++; y1 <= y2; y1++) { if (d < 0) { d += Eincr; /* Choose the Eastern Pixel */ } else { d += NEincr; /* Choose the North Eastern Pixel */ x1 += yincr; /* (or SE pixel for dx/dy < 0!) */ } putPixel(x1,y1,color); /* Draw the point */ } } }