Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

#include "drivers/glib.h"
#include <stdlib.h>

#include "vga.h"

#define fontaddr       0xffa6eL     /* indirizzo set caratteri         */

BYTE * flbaddr;
WORD  bpr;
WORD  height, width;

inline void memsetw(void *dst, unsigned int c, unsigned long int memdiv2)
{
          __asm__ __volatile__("push %%edi
                                push %%eax
                                push %%ecx
                                movl %2, %%edi
                                cld
                                rep
                                stosw
                                pop %%ecx
                                pop %%eax
                                pop %%edi"

                                :
                                : "c" (memdiv2), "a" (c), "b" (dst));

}


static void circlepixels(WORD x, WORD y, WORD sx, WORD sy, DWORD c)
{
    grx_plot(sx + x, sy + y, c);
    grx_plot(sx - x, sy + y, c);
    grx_plot(sx + x, sy - y, c);
    grx_plot(sx - x, sy - y, c);
    grx_plot(sx + y, sy + x, c);
    grx_plot(sx - y, sy + x, c);
    grx_plot(sx + y, sy - x, c);
    grx_plot(sx - y, sy - x, c);
}

void grx_circle(WORD sx, WORD sy, WORD r, DWORD c)
{
    int x, y, d;
   
        if (r < 1) {
        grx_plot(sx, sy, c);
        return;
    }
    x = 0;
    y = r;
    d = 1 - r;
    circlepixels(x, y, sx, sy, c);
    while (x < y) {
        if (d < 0)
            d += x * 2 + 3;
        else {
            d += x * 2 - y * 2 + 5;
            y--;
        }
        x++;
        circlepixels(x, y, sx, sy, c);
    }
}

/* grx_disc by Massy */

static __inline__ void discpixels(WORD x, WORD y, WORD sx, WORD sy, DWORD c)
{
    grx_line(sx + x, sy + y, sx + x, sy - y, c);
    grx_line(sx - x, sy + y, sx - x, sy - y, c);
    grx_line(sx + y, sy + x, sx + y, sy - x , c);
    grx_line(sx - y, sy + x, sx - y, sy - x , c);
}

void grx_disc(WORD sx, WORD sy, WORD r, DWORD c)
{
    int x, y, d;
   
        if (r < 1) {
        grx_plot(sx, sy, c);
        return;
    }
    x = 0;
    y = r;
    d = 1 - r;
    discpixels(x, y, sx, sy, c);
    while (x < y) {
        if (d < 0)
            d += x * 2 + 3;
        else {
            d += x * 2 - y * 2 + 5;
            y--;
        }
        x++;   
        discpixels(x, y, sx, sy, c);
    }
}

int grx_setbuffer(BYTE *vbuf, WORD w, WORD h)
{

    //This functions are designed to work only whit 16 bpp
       
    flbaddr = vbuf;
    width = w;
    height = h;
    bpr = 2 * w;
       
    return 1;
   
}

void grx_clear(DWORD color)
{

    grx_box(0, 0, width, height, color);

}

void grx_putimage(WORD x1, WORD y1, WORD x2, WORD y2, BYTE *buf)
{
   
}

void grx_box(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
    BYTE * addr;
    int dx, y;
   
    addr = flbaddr + (x1 << 1) + bpr * y1;
    dx = (x2 - x1 + 1) << 1;

    for (y = y1; y <= y2; y++) {
        memsetw(addr,color,(dx>>1));
        addr += bpr;
    }
}

void grx_rect(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
    BYTE * addr;
    int dx, y;
   
    addr = flbaddr + (x1 << 1) + bpr * y1;
    dx = (x2 - x1) << 1;

    memsetw(addr,color,(dx>>1)+1);
    addr += bpr;

    for (y = y1 + 1; y <= y2 - 1; y++) {
        *(WORD *)(addr) = (WORD)(color);
        *(WORD *)(addr + dx) = (WORD)(color);
        addr += bpr;
    }
    memsetw(addr,color,(dx>>1)+1);
   
}

void grx_text(char *text, WORD x, WORD y, DWORD fg, DWORD bg)
{
    BYTE * fp;
    BYTE * addr;
    int r, c, bits;

    addr = flbaddr;
    while (*text) {
        fp = (BYTE *)(fontaddr + (8 * *(BYTE *)text));
        for (r=0; r<8; r++) {
            bits = *(BYTE *)(fp++);
            for (c=0; c<8; c++)
                if (bits & (0x80>>c))
                    *(WORD *)(addr + (y + r) * bpr + ((x + c) << 1)) = (WORD)(fg);
                else
                    *(WORD *)(addr + (y + r) * bpr + ((x + c) << 1)) = (WORD)(bg);
        }
        text++;
        x += 8;
    }
}

void grx_line(WORD x1, WORD y1, WORD x2, WORD y2, DWORD color)
{
    register int t, distance;
    BYTE * addr;
    int xerr=0, yerr=0, deltax, deltay;
    int incx, incy;

    addr = flbaddr;;
    deltax = x2 - x1;                   /* compute both distances */
    deltay = y2 - y1;

    if (deltax > 0)                     /* compute increments */
        incx = 1;
    else if (deltax == 0)
        incx = 0;
    else
        incx = -1;

    if (deltay > 0)
        incy = 1;
    else if (deltay == 0)
        incy = 0;
    else
        incy = -1;

    deltax = abs(deltax);               /* determine greater distance */
    deltay = abs(deltay);
    if (deltax > deltay)
        distance = deltax;
    else
        distance = deltay;

    for (t=0; t<=distance+1; t++) {     /* draw the line */
        *(WORD *)(addr + y1 * bpr + (x1 << 1)) = (WORD)color;
        xerr += deltax;
        yerr += deltay;
        if (xerr > distance) {
            xerr -= distance;
            x1 += incx;
        }
        if (yerr > distance) {
            yerr -= distance;
            y1 += incy;
        }
    }
}

void grx_plot(WORD x, WORD y, DWORD color)
{
    *(WORD *)(flbaddr + y * bpr + (x << 1))  =  (WORD)color;
}

DWORD grx_getpixel(WORD x, WORD y)
{
    DWORD rv;

    (DWORD)rv = *(WORD *)(flbaddr + y * bpr + (x << 1));
    return rv;
}