/////////////////////////////////////////////////////////////////////////////////////////////////
//显存换页函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl set_vbe_page(int page)
{
    if (g_cur_vbe_page != page)
    {
        _BX = 0;
        _DX = g_cur_vbe_page = page;
        _AX = 0x4F05;
        __int__(0x10);
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//读像素点函数
/////////////////////////////////////////////////////////////////////////////////////////////////
char _Cdecl GetPixel(int x, int y)
{
    long addr;
    int  page;
    char far *videoptr = (char far *)0xa0000000L;
    addr = VRAM_GRAPH_800X600X256(x,y);
    page = (int)(addr >> 16);
    set_vbe_page(page);
    return *(videoptr + (unsigned)(addr & 0xffff));
//  return (peekb(0xa000, (unsigned)(addr & 0xFFFF) ));
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//画点函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl PutPixel(int x,int y,int color)
{
    int page;
    long addr;
    char far *videoptr = (char far *)0xa0000000L;
    if (x < 800 && y < 600)
    {
        addr = VRAM_GRAPH_800X600X256(x,y);
        page = (int)(addr >> 16);
        set_vbe_page(page);
//        pokeb(0xa000, (unsigned)(addr & 0xFFFF),color);
        *(videoptr+(unsigned int)(addr&0xffff))= color;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////绘制一条垂直线函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Vline(int x, int y1, int y2)
{
    int i,gcolor = getcolor();
    for (i = y1; i <= y2; ++i)
        PutPixel(x,i,gcolor);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////绘制一条水平线函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Hline(int x1, int y, int x2)
{
    int i,gcolor = getcolor();
    for (i=x1;i<=x2;i++)
        PutPixel(i,y,gcolor);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////通用画线子程序
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Line(int x1,int y1,int x2,int y2)
{
    register int t,d;
    int xer=0,yer=0,deta_x,deta_y,incx,incy;
    int gcolor = getcolor();
    deta_x = x2 - x1;
    deta_y = y2 - y1;
    if (deta_x>0)
       incx = 1;
    else if(deta_x == 0)
        incx = 0;
    else
        incx = -1;
    if (deta_y>0)
        incy = 1;
    else if (deta_y == 0)
        incy = 0;
    else
        incy = -1;
    deta_x = abs(deta_x);
    deta_y = abs(deta_y);
    if (deta_x>deta_y)
        d = deta_x;
    else
        d = deta_y;
    for (t=0;t<=d+1;t++)
    {
        PutPixel(x1,y1,gcolor);
        xer += deta_x;
        yer += deta_y;
        if (xer>d)
        {
            xer -= d;
            x1 += incx;
        }
        if (yer>d)
        {
            yer -= d;
            y1 += incy;
        }
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////画矩形
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Rectangle(int x1,int y1,int x2,int y2)
{
    Hline(x1, y1, x2);
    Hline(x1, y2, x2);
    Vline(x1, y1, y2);
    Vline(x2, y1, y2);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////填充矩形
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Bar(int x1, int y1, int x2, int y2)
{
    int i,gcolor = getcolor();
    setcolor(Fill_Color);
    for (i = y1; i <= y2; ++i)
        Hline(x1, i, x2);
    setcolor(gcolor);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////画圆函数,以(c_x, c_y)为中心画一半径为r的圆
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl Circle(int c_x, int c_y, int r)
{
    int x = 0, y = r, d0, d1, d2, direction;
    int gcolor = getcolor();
    d0 = (1-r) << 1;
    while (y >= 0)
    {
        PutPixel(c_x + x, c_y + y, gcolor);
        PutPixel(c_x - x, c_y - y, gcolor);
        PutPixel(c_x + x, c_y - y, gcolor);
        PutPixel(c_x - x, c_y + y, gcolor);
        if (d0 < 0)
        {
            d1 = ((d0 + y) << 1) -1;
            if (d1 <= 0) direction = 1;
            else direction = 2;
        }
        else if (d0 > 0)
        {
            d2 = ((d0 - x) << 1) - 1;
            if (d2 <= 0) direction = 2;
            else direction = 3;
        }
        else direction = 2;
        switch(direction)
        {
            case 1 : ++x;
                d0 += (x<<1) + 1;
                break;
            case 2 : ++x;
                --y;
                d0+=(x-y+1)<<1;
                break;
            case 3 : --y;
                d0 += -(y<<1) + 1;
                break;
        }
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////填充的圆形,使用的是Midpoint算法
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl CircleFill(int x0, int y0, int r)
{
    int x,y;
    int deltax,deltay;
    int d,gcolor = getcolor();
    x = 0;
    y = r;
    deltax = 3;
    deltay = 2 - (r << 1);
    d = 1 - r;
    setcolor(getfillcolor());
    while (x <= y)
    {
        Hline(x0-x, y0+y, x0+x) ;
        Hline(x0-x, y0-y, x0+x);
        Hline(x0-y, y0-x, x0+y);
        Hline(x0-y, y0+x, x0+y);
        Hline(x0-x, y0+y, x0+x);
        if(d<0)
        {
            d += deltax;
            deltax += 2;
            x++;
        }
        else
        {
            d += deltax+deltay;
            deltax += 2;
            deltay += 2;
            x++;
            y--;
         }
    }
   setcolor(gcolor);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////图形模式初始化子程序
/////////////////////////////////////////////////////////////////////////////////////////////////
void _Cdecl InitGraph(void)
{
    _AX = 0x4F02;
    _BX = VBE800X600X256;
    __int__(0x10);
    if (_AH != 0)
    {
        puts("Can't Initialize the graphics mode!");
        exit(1);
    }
}
//////////////////////////////////////////////////////////////////////////////
////关闭图形模式,回到文本模式子程序
//////////////////////////////////////////////////////////////////////////////
void _Cdecl CloseGraph(void)
{
    _AX = 0x4F02;
    _BX = 0x03;
    __int__(0x10);
}