⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svgac.c

📁 VESA 图形编程的汇编子程序库
💻 C
📖 第 1 页 / 共 2 页
字号:
				blueMask = 0x1F;	bluePos = 0;	blueAdjust = 3;
				break;
			case 16:
				redMask = 0x1F;		redPos = 11;	redAdjust = 3;
				greenMask = 0x3F;	greenPos = 5;	greenAdjust = 2;
				blueMask = 0x1F;	bluePos = 0;	blueAdjust = 3;
				break;
			case 24:
				redMask = 0xFF;		redPos = 16;	redAdjust = 0;
				greenMask = 0xFF;	greenPos = 8;	greenAdjust = 0;
				blueMask = 0xFF;	bluePos = 0;	blueAdjust = 0;
				break;
			}
		}
	else if (*memmodel == memRGB) {
        /* Convert the 32k direct color modes of VBE 1.2+ BIOSes to
         * be recognised as 15 bits per pixel modes.
         */

        if (*bitsperpixel == 16 && modeInfo.RsvdMaskSize == 1)
			*bitsperpixel = 15;

		/* Save direct color info mask positions etc */

		redMask = (0xFF >> (redAdjust = 8 - modeInfo.RedMaskSize));
		redPos = modeInfo.RedFieldPosition;
		greenMask = (0xFF >> (greenAdjust = 8 - modeInfo.GreenMaskSize));
		greenPos = modeInfo.GreenFieldPosition;
		blueMask = (0xFF >> (blueAdjust = 8 - modeInfo.BlueMaskSize));
		bluePos = modeInfo.BlueFieldPosition;
		}
    if (mode == 0x13 && !extendedflipping)
        *maxpage = 0;
    else
		computePageInfo(&modeInfo,maxpage,pagesize);
	return true;
}

typedef struct {
    short   writeBankLen;
    void    *writeBank;
    short   readBankLen;
    void    *readBank;
    short   newPageLen;
    void    *newPage;
    } PMInfoBlock;

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.
*
****************************************************************************/
{
    ModeInfoBlock   modeInfo;
    PMInfoBlock     *pmInfo = (PMInfoBlock*)&modeInfo;
    union REGS      regs;
    struct SREGS    sregs;
    int             bitsperpixel,memmodel;

	regs.x.ax = 0x0F00;
    int86(0x10,&regs,&regs);
    oldMode = regs.x.ax & 0x7F;         /* Save old video mode          */
    old50Lines = false;                 /* Default to 25 line mode      */
    if (oldMode == 0x3) {
        regs.x.ax = 0x1130;
        regs.x.bx = 0;
        regs.x.dx = 0;
        int86(0x10,&regs,&regs);
        old50Lines = (regs.h.dl == 49);
        }

    regs.x.ax = 0x4F02;
    regs.x.bx = mode;
    int86(0x10,&regs,&regs);            /* Set the video mode           */
    if (regs.x.ax != 0x004F)
        return false;

    getSuperVGAModeInfo(mode,&maxx,&maxy,&bytesperline,&bitsperpixel,
        &memmodel,&maxpage,&pagesize);
    maxx--; maxy--;

	/* Now set up the vectors to the correct routines for the video
	 * mode type.
	 */

	switch (bitsperpixel) {
		case 4:
			putPixel = _putPixel16;
			clear = _clear16;
			maxcolor = defcolor = 15;
			break;
		case 8:
			putPixel = _putPixel256;
			clear = _clear256;
			maxcolor = 255;
			defcolor = 15;
			break;
		case 15:
			putPixel = _putPixel32k;
			clear = _clear32k;
			maxcolor = defcolor = 0x7FFF;
			break;
		case 16:
			putPixel = _putPixel64k;
			clear = _clear64k;
			maxcolor = defcolor = 0xFFFF;
			break;
		case 24:
			putPixel = _putPixel16m;
			clear = _clear16m;
			maxcolor = defcolor = 0xFFFFFF;
			break;
		}

	if (mode <= 0x13) {
        /* This is a normal VGA style mode, so we need to determine the
         * correct information for bank switching from the BIOS
         */

        if (mode == 0x13)
            mode = 0x101;
        else
            mode = 0x102;
        }
    sregs.es = SEG(&modeInfo);
    regs.x.di = OFF(&modeInfo);
    regs.x.ax = 0x4F01;
    regs.x.cx = mode;
    int86x(0x10,&regs,&regs,&sregs);    /* Get mode information         */
    bankAdjust = 64 / modeInfo.WinGranularity;
    curBank = -1;
	bankSwitch = modeInfo.WinFuncPtr;

	/* Now set up the vectors to the appropriate bank switching routines.
     * If the Universal VESA VBE is installed, we can move the bank
     * switching routines from there into our own code space for speed
     * (especially under protected mode).
     */

    sregs.es = SEG(&modeInfo);
    regs.x.di = OFF(&modeInfo);
    regs.x.ax = 0x4F01;
    regs.x.cx = -1;
    int86x(0x10,&regs,&regs,&sregs);    /* Get mode information         */
    writeBank = readBank = pageFlip = NULL;
    if (regs.x.ax == 0x004F && regs.x.cx == 0xCABD) {
        /* The Universal VESA VBE is there and functioning, so copy the
         * routines onto the heap and execute from there.
         */

        writeBank = malloc(pmInfo->writeBankLen);
        memcpy(writeBank,pmInfo->writeBank,pmInfo->writeBankLen);
        if (pmInfo->readBankLen > 0) {
            readBank = malloc(pmInfo->readBankLen);
			memcpy(readBank,pmInfo->readBank,pmInfo->readBankLen);
			}
		pageFlip = malloc(pmInfo->newPageLen);
		memcpy(pageFlip,pmInfo->newPage,pmInfo->newPageLen);
		}

	return true;
}

PUBLIC void restoreMode(void)
/****************************************************************************
*
* Function:     restoreMode
*
* Description:  Restore the previous video mode in use before the SuperVGA
*               mode was set. This routine will also restore the 50 line
*               display mode if this mode was previously set.
*
****************************************************************************/
{
	union REGS  regs;

	regs.x.ax = oldMode;
	int86(0x10,&regs,&regs);            /* Set the old video mode       */
	if (old50Lines) {
		regs.x.ax = 0x1112;
		regs.x.bx = 0;
		int86(0x10,&regs,&regs);        /* Restore 50 line mode         */
		}
}

void setSuperVGADisplayStart(int x,int y)
/****************************************************************************
*
* Function:     setDisplayStart
* Parameters:   x,y - Position of the first pixel to display
*
* Description:  Sets the new starting display position to implement
*               hardware scrolling.
*
****************************************************************************/
{
	union REGS  regs;

	if (extendedflipping) {
		regs.x.ax = 0x4F07;
		regs.x.bx = 0x0000;
		regs.x.cx = x;
		regs.x.dx = y;
		int86(0x10,&regs,&regs);
		}
}

long rgbColor(uchar r,uchar g,uchar b)
/****************************************************************************
*
* Function:     rgbColor
*
* Returns:      Value representing the color. The value is converted from
*               24 bit RGB space into the appropriate color for the
*               video mode.
*
****************************************************************************/
{
	return ((long)((r >> redAdjust) & redMask) << redPos)
		 | ((long)((g >> greenAdjust) & greenMask) << greenPos)
		 | ((long)((b >> blueAdjust) & blueMask) << bluePos);
}

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
*               color       - Color to draw the line in
*
* 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                   */
            }
        }
}

PUBLIC void writeText(int x,int y,uchar *str,long color)
/****************************************************************************
*
* Function:     writeText
* Parameters:   x,y     - Position to begin drawing string at
*               str     - String to draw
*
* Description:  Draws a string using the BIOS 8x16 video font by plotting
*               each pixel in the characters individually. This should
*               work for all video modes.
*
****************************************************************************/
{
    uchar           byte;
    int             i,j,k,length,ch;
    uchar           *font;

    font = getFontVec();
    length = strlen(str);
    for (k = 0; k < length; k++) {
        ch = str[k];
        for (j = 0; j < 16; j++) {
            byte = *(font + ch * 16 + j);
            for (i = 0; i < 8; i++) {
                if ((byte & 0x80) != 0)
                    putPixel(x+i,y+j,color);
                byte <<= 1;
                }
            }
        x += 8;
        }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -