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

📄 lowgdi.c

📁 做为linux下图形用户界面支持系统之一的MicroWindows采用C++设计
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * Lowgdi.c: 低階繪圖介面
 *
 ****************************************************************************/

#include <dos.h>
#include "lowgdi.h"
extern char engfont[1920];

/* useful macros */
#define _lgVideoCall(a, b, c, d)    _DX=d; _CX=c; _BX=b; _AX=a; \
                                    geninterrupt(0x10);
#define _lgMouseCall(a, b, c, d)    _DX=d; _CX=c; _BX=b; _AX=a; \
                                    geninterrupt(0x33);
#define _lgOutportb(a, b)           outportb(a, b)
#define _lgAL                       _AL
#define _lgBL                       _BL
#define _lgAX                       _AX
#define _lgBX                       _BX
#define _lgCX                       _CX
#define _lgDX                       _DX

/* global variables */
int     _lgClipX1 = 0, _lgClipY1 = 0, _lgClipX2 = 639, _lgClipY2 = 479;
BOOL    _lgClipOut = FALSE;
int     _lgRX1 = 0, _lgRY1 = 0, _lgRX2 = 0, _lgRY2 = 0;
int     _lgScreenWidth = 640, _lgScreenHeight = 480;
int     _lgColor = LG_WHITE, _lgBgColor = LG_BLACK;
BOOL    _lgXOR = FALSE;
int     _lgYaddr[500];
BYTE far *_lgDBitmap = (BYTE far*)0xa0000000;
BYTE    _lgMask[8]      ={0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1};
BYTE    _lgLeftMask[8]  ={0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
BYTE    _lgRightMask[8] ={0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
BYTE    _lgBitPlane [8] ={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
BOOL    _lgMouseActive = TRUE, _lgCursorTempHide = FALSE;
BYTE    _lgMSavedImage[256];
int     _lgMLastX = 0, _lgMLastY = 0, _lgMButton = 0;
BOOL    _lgMLButtonHitted = FALSE;
BOOL    _lgMouseHided = FALSE;

BYTE _lgMScreenMask[32]=
{
    0x3f, 0xff, 0x1f, 0xff, 0x0f, 0xff, 0x07, 0xff, 0x03, 0xff,
    0x01, 0xff, 0x00, 0xff, 0x00, 0x7f, 0x00, 0x3f, 0x00, 0x1f,
    0x01, 0xff, 0x10, 0xff, 0x30, 0xff, 0xf8, 0x7f, 0xf8, 0x7f,
    0xfc, 0x3f
};

BYTE _lgMCursorMask[32]=
{
    0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00,
    0x7c, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x7f, 0x80, 0x7f, 0xc0,
    0x7c, 0x00, 0x46, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, 0x00,
    0x00, 0x00
};

#define _lgClipAccept(a, b)     (a|b)
#define _lgClipReject(a, b)     (a&b)
#define _lgClipTop              0x08
#define _lgClipBottom           0x04
#define _lgClipRight            0x02
#define _lgClipLeft             0x01
#define _lgClipInside           0x00

void _lgLineClipper(int x1, int y1, int x2, int y2);
void _lgRectClipper(int x1, int y1, int x2, int y2);
int  _lgClipOutcode(int x , int y);
void _lgHline (int x1, int x2, int y);
void _lgVline (int x, int y1, int y2);
void _lgDisplayCursor (void);
void _lgUpdateMouse (void);
void _lgMouseTempHide (int x1, int y1, int x2, int y2);
void _lgMouseTempShow (void);
void _lgMSaveBack (void);
void _lgMRestoreBack (void);
void _lgLowPoint (int x, int y);

BOOL    _lgOpenGraphics()
{
    int i;

    _lgVideoCall (0x101a, 0xffff, 0, 0);    /* detect if VGA exists */
    if (_lgBX==0xffff) return (FALSE);      /* VGA not exists! */

    _lgVideoCall (0x12, 0, 0, 0);
    for (i=0; i<500; i++) _lgYaddr[i]=80 * i;

    /* set write mode 2 */
    _lgOutportb (0x3ce, 5);
    _lgOutportb (0x3cf, 2);

    /* set pen normal */
    _lgOutportb (0x3ce, 3);
    _lgOutportb (0x3cf, 0);

    /* initial the mouse */
    _lgMouseCall (0, 0, 0, 0);
    if (!_lgAX)
    {
        _lgMouseActive=FALSE;
        return (TRUE);
    }
    
    _lgMouseCall (2, 0, 0, 0);      /* disable the text cursor */
    _lgMouseCall (4, 0, _lgScreenWidth/2, _lgScreenHeight/2);  /* centerize */
    _lgMouseCall (7, 0, 0, _lgScreenWidth-1);   /* set X range */
    _lgMouseCall (8, 0, 0, _lgScreenHeight-1);  /* set Y range */
    _lgMSaveBack();
    _lgDisplayCursor();

    return (TRUE);
}

BOOL    _lgCloseGraphics()
{
    /* return to VGA colored text mode 80x25 */
    _lgVideoCall (0x03, 0, 0, 0);

    if (_lgMouseActive == TRUE)
    {
        _lgMouseCall (0x31, 0, 0, 0);       /* deinitial the mouse */
    }

    return (TRUE);
}

void    _lgRect     (int x1, int y1, int x2, int y2)
{
    _lgLine (x1, y1, x2, y1);
    _lgLine (x1, y2, x2, y2);
    _lgLine (x1, y1, x1, y2);
    _lgLine (x2, y1, x2, y2);
}

void    _lgPoint    (int x, int y)
{
    unsigned addr=_lgYaddr[y] + (x >> 3);
    BYTE mask = _lgMask[x & 7];

    if (x<_lgClipX1 || y<_lgClipY1 || x>_lgClipX2 || y>_lgClipY2) return;

    _lgMouseTempHide (x, y, x, y);
    _lgOutportb (0x3ce, 8);         /* setup latch register */
    _lgOutportb (0x3cf, mask);
    mask=*(_lgDBitmap+addr);
    *(_lgDBitmap+addr)=_lgColor;
    _lgMouseTempShow ();
}

void    _lgLowPoint (int x, int y)
{
    unsigned addr=_lgYaddr[y] + (x >> 3);
    BYTE mask = _lgMask[x & 7];
    _lgOutportb (0x3ce, 8);         /* setup latch register */
    _lgOutportb (0x3cf, mask);
    mask=*(_lgDBitmap+addr);
    *(_lgDBitmap+addr)=_lgColor;
}

void    _lgLine     (int x1, int y1, int x2, int y2)
{
    int dx, dy, i, e, incx, incy, inc1, inc2, x, y, tmp;

    _lgLineClipper (x1, y1, x2, y2);
    if (_lgClipOut) return;
    _lgMouseTempHide (_lgRX1, _lgRY1, _lgRX2, _lgRY2);

    if (_lgRX1==_lgRX2)
    {
        if (_lgRY1 > _lgRY2)
        {
            tmp=_lgRY2;
            _lgRY2=_lgRY1;
            _lgRY1=tmp;
        }

        _lgVline (_lgRX1, _lgRY1, _lgRY2);
    }
    else if (_lgRY1==_lgRY2)
    {
        if (_lgRX1 > _lgRX2)
        {
            tmp=_lgRX2;
            _lgRX2=_lgRX1;
            _lgRX1=tmp;
        }

        _lgHline (_lgRX1, _lgRX2, _lgRY1);
    }
    else
    {

        dx=_lgRX2-_lgRX1;
        dy=_lgRY2-_lgRY1;

        if (dx<0) dx=-dx;
        if (dy<0) dy=-dy;

        if (x2<x1) incx=-1; else incx=1;
        if (y2<y1) incy=-1; else incy=1;

        x=_lgRX1;
        y=_lgRY1;

        if (dx > dy)
        {
            _lgLowPoint (x, y);

            e       = 2* dy - dx;
            inc1    = 2* (dy-dx);
            inc2    = 2* dy;

            for (i=0; i<dx; i++)
            {
                if (e>=0)
                {
                    y+=incy;
                    e+=inc1;
                }
                else e+=inc2;

                x+=incx;
                _lgLowPoint (x, y);
            }
        }
        else
        {
            _lgLowPoint (x, y);
            e       = 2* dx - dy;
            inc1    = 2* (dx-dy);
            inc2    = 2* dx;

            for (i=0; i<dy; i++)
            {
                if (e>=0)
                {
                    x+=incx;
                    e+=inc1;
                }
                else e+=inc2;

                y+=incy;
                _lgLowPoint (x, y);
            }
        }
    }

    _lgMouseTempShow();
}

void    _lgSolidRect(int x1, int y1, int x2, int y2)
{
    int y;

    _lgRectClipper (x1, y1, x2, y2);
    if (_lgClipOut) return;
    _lgMouseTempHide (_lgRX1, _lgRY1, _lgRX2, _lgRY2);

    for (y=_lgRY1; y<=_lgRY2; y++)
    {
        _lgHline (_lgRX1, _lgRX2, y);
    }

    _lgMouseTempShow();
}

void _lgDrawText (int x, int y, char *text)
{
    int i, l = strlen (text), xc = x;
    char *fontptr;

    _lgRectClipper (x, y, x + l*8 - 1, y + 14);
    if (_lgClipOut) return;
    _lgMouseTempHide (_lgRX1, _lgRY1, _lgRX2, _lgRY2);

    for (i = 0; i < l; i++, xc += 8)
    {
        if ((unsigned)*text > 127) continue;      /* high-byte char omitted */
        fontptr = engfont + (*text++) * 15;
        _lgPutFont (fontptr, xc, y, 8, 15);
    }

    _lgMouseTempShow();
}



void _lgHline (int x1, int x2, int y)
{
    register unsigned int i;
    unsigned int addr=_lgYaddr[y], startx, endx;
    static BYTE mask;

    startx=x1 >> 3;
    endx  =x2 >> 3;

    _lgOutportb (0x3ce, 8);

    if (startx==endx)
    {

        if (x2 & 7) mask=_lgLeftMask[x1 & 7] & _lgRightMask[x2 & 7];
        else mask=_lgLeftMask[x1 & 7];
        _lgOutportb (0x3cf, mask);
        addr+=startx;
        mask=*(_lgDBitmap+addr);
        *(_lgDBitmap+addr)=_lgColor;
    }
    else
    {
        /* draw the left side */
        addr+=startx;
        mask=_lgLeftMask[x1 & 7];
        _lgOutportb (0x3cf, mask);

        mask=*(_lgDBitmap+addr);
        *(_lgDBitmap+addr)=_lgColor;

        _lgOutportb (0x3cf, 0xff);
        for (i=startx+1; i<endx; i++)
        {
            addr++;
            mask=*(_lgDBitmap+addr);
            *(_lgDBitmap+addr)=_lgColor;
        }

        /* draw the right side */
        addr++;
        mask=_lgRightMask[x2 & 7];
        _lgOutportb (0x3cf, mask);
        mask=*(_lgDBitmap+addr);
        *(_lgDBitmap+addr)=_lgColor;
    }
}

void _lgVline (int x, int y1, int y2)
{
    register unsigned int i;
    unsigned addr;
    BYTE mask=_lgMask[x & 7], tmp;

    _lgOutportb (0x3ce, 8);
    _lgOutportb (0x3cf, mask);

    for (i=y1; i<=y2; i++)
    {
        addr = _lgYaddr[i] + (x >> 3);
        tmp = *(_lgDBitmap + addr);
        *(_lgDBitmap+addr)=_lgColor;
    }

    if (tmp) ;
}


int     _lgGetScreenWidth()
{
    return (_lgScreenWidth);
}

int     _lgGetScreenHeight()
{
    return (_lgScreenHeight);
}

int     _lgGetColor ()
{
    return (_lgColor);
}

int     _lgGetBgColor ()
{
    return (_lgBgColor);
}

BOOL    _lgGetXOR ()
{
    return (_lgXOR);
}

BOOL _lgIsMouseActive()
{
    return (_lgMouseActive);
}

void    _lgSetColor (int c)
{
    _lgColor = c;
}

void    _lgSetBgColor (int c)
{
    _lgBgColor = c;
}

void    _lgSetXOR (BOOL xor)
{
    _lgXOR = xor;
    if (xor == TRUE)
    {
        _lgOutportb (0x3ce, 3);
        _lgOutportb (0x3cf, 0x18);
    }
    else
    {
        _lgOutportb (0x3ce, 3);
        _lgOutportb (0x3cf, 0);
    }
}

void    _lgResetClipping()
{
    _lgSetClippingRect (0, 0, _lgScreenWidth-1, _lgScreenHeight-1);
}

void    _lgSetClippingRect(int x1, int y1, int x2, int y2)
{
    int x3, y3, x4, y4;

    /* swapping */
    x3=x1<x2 ? x1:x2;
    x4=x1>x2 ? x1:x2;
    y3=y1<y2 ? y1:y2;
    y4=y1>y2 ? y1:y2;

    if (x3 < 0) x3 = 0;
    if (y3 < 0) y3 = 0;
    if (x4 < 0) x4 = 0;
    if (y4 < 0) y4 = 0;

    if (x3 > _lgScreenWidth-1)     x3=_lgScreenWidth-1;
    if (y3 > _lgScreenHeight-1)    y3=_lgScreenHeight-1;
    if (x4 > _lgScreenWidth-1)     x4=_lgScreenWidth-1;
    if (y4 > _lgScreenHeight-1)    y4=_lgScreenHeight-1;

    _lgClipX1=x3;
    _lgClipY1=y3;
    _lgClipX2=x4;
    _lgClipY2=y4;
}

void _lgMSaveBack()
{
    BOOL xor = _lgXOR;
    if (_lgMouseHided || _lgCursorTempHide) return;

    _lgSetXOR (FALSE);
    _lgGetImage (_lgMSavedImage, _lgMLastX, _lgMLastY,
                                 _lgMLastX+15, _lgMLastY+15);
    _lgSetXOR (xor);
}

void _lgMRestoreBack()
{
    BOOL xor = _lgXOR;
    if (_lgMouseHided || _lgCursorTempHide) return;

    _lgSetXOR (FALSE);
    _lgPutImage (_lgMSavedImage, _lgMLastX, _lgMLastY,
                                 _lgMLastX+15, _lgMLastY+15);
    _lgSetXOR (xor);
}

void _lgDisplayCursor ()
{
    int bc=_lgColor, bgc=_lgBgColor;
    int bcx1=_lgClipX1, bcx2=_lgClipX2, bcy1=_lgClipY1, bcy2=_lgClipY2;

    if (_lgMouseHided || _lgCursorTempHide) return;

⌨️ 快捷键说明

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