1377 lines
31 KiB
C
1377 lines
31 KiB
C
|
/* driver.c Framebuffer primitives */
|
||
|
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <vga.h>
|
||
|
|
||
|
#include "inlstring.h" /* include inline string operations */
|
||
|
#include "vgagl.h"
|
||
|
#include "def.h"
|
||
|
#include "driver.h"
|
||
|
|
||
|
|
||
|
#define MAXBYTEWIDTH 4096 /* used in bitblt emulation */
|
||
|
|
||
|
/* All functions that simply call another function with slightly different
|
||
|
* parameter values are declared inline. */
|
||
|
#define INLINE inline
|
||
|
|
||
|
#define NOTIMPL(s) { notimplemented(s); return; }
|
||
|
|
||
|
/* in: vp = video offset; out: rvp = video pointer, chunksize, page */
|
||
|
#define SETWRITEPAGED(vp, rvp, chunksize, page) \
|
||
|
page = vp >> 16; \
|
||
|
vga_setpage(page); \
|
||
|
rvp = (vp & 0xffff) + VBUF; \
|
||
|
chunksize = 0x10000 - (vp & 0xffff);
|
||
|
|
||
|
static inline int RGB2BGR(int c)
|
||
|
{
|
||
|
/* a bswap would do the same as the first 3 but in only ONE! cycle. */
|
||
|
/* However bswap is not supported by 386 */
|
||
|
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED)
|
||
|
#ifdef NO_ASSEMBLY
|
||
|
c = ((c >> 0) & 0xff) << 16 |
|
||
|
((c >> 8) & 0xff) << 8 |
|
||
|
((c >> 16) & 0xff) << 0;
|
||
|
#else
|
||
|
asm("rorw $8, %0\n" /* 0RGB -> 0RBG */
|
||
|
"rorl $16, %0\n" /* 0RBG -> BG0R */
|
||
|
"rorw $8, %0\n" /* BG0R -> BGR0 */
|
||
|
"shrl $8, %0\n" /* 0BGR -> 0BGR */
|
||
|
: "=q"(c):"0"(c));
|
||
|
#endif
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
/* RGB_swapped_memcopy returns the amount of bytes unhandled */
|
||
|
static inline int RGB_swapped_memcpy(char *dest, char *source, int len)
|
||
|
{
|
||
|
int rest, tmp;
|
||
|
|
||
|
tmp = len / 3;
|
||
|
rest = len - 3 * tmp;
|
||
|
len = tmp;
|
||
|
|
||
|
while (len--) {
|
||
|
*dest++ = source[2];
|
||
|
*dest++ = source[1];
|
||
|
*dest++ = source[0];
|
||
|
source += 3;
|
||
|
}
|
||
|
|
||
|
return rest;
|
||
|
}
|
||
|
|
||
|
static void notimplemented(char *s)
|
||
|
{
|
||
|
printf("vgagl: %s not implemented.\n", s);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* One byte per pixel frame buffer primitives */
|
||
|
|
||
|
#define ASSIGNVP8(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x);
|
||
|
#define ASSIGNVPOFFSET8(x, y, vp) vp = (y) * BYTEWIDTH + (x);
|
||
|
|
||
|
void __svgalib_driver8_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
*vp = c;
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
*(VBUF + (vp & 0xffff)) = c;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver8_getpixel(int x, int y)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
return *vp;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver8p_getpixel(int x, int y)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
return *(VBUF + (vp & 0xffff));
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP8(x1, y, vp);
|
||
|
__memset(vp, c, x2 - x1 + 1);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
char *rvp;
|
||
|
int l;
|
||
|
int chunksize, page;
|
||
|
ASSIGNVPOFFSET8(x1, y, vp);
|
||
|
SETWRITEPAGED(vp, rvp, chunksize, page);
|
||
|
l = x2 - x1 + 1;
|
||
|
if (l <= chunksize)
|
||
|
__memset(rvp, c, l);
|
||
|
else {
|
||
|
__memset(rvp, c, chunksize);
|
||
|
vga_setpage(page + 1);
|
||
|
__memset(VBUF, c, l - chunksize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
int i;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memset(vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8a_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
if (w * h < 128)
|
||
|
(*__svgalib_nonaccel_fillbox)(x, y, w, h, c);
|
||
|
else {
|
||
|
vga_accel(ACCEL_SETFGCOLOR, c);
|
||
|
vga_accel(ACCEL_FILLBOX, x, y, w, h);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
int page;
|
||
|
int i;
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
__memset(VBUF + vp, c, 0x10000 - vp);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memset(VBUF, c, (vp + w) & 0xffff);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memset(VBUF + vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
bp = b;
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(vp, bp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
/* extra argument width of source bitmap, so that putboxpart can use this */
|
||
|
int vp;
|
||
|
int page;
|
||
|
char *bp = b;
|
||
|
int i;
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
__memcpy(VBUF + vp, bp, 0x10000 - vp);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memcpy(VBUF, bp + 0x10000 - vp,
|
||
|
(vp + w) & 0xffff);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
bp += bw;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memcpy(VBUF + vp, bp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
bp = b;
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(bp, vp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
int vp;
|
||
|
int page;
|
||
|
char *bp = b;
|
||
|
int i;
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
__memcpy(bp, VBUF + vp, 0x10000 - vp);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memcpy(bp + 0x10000 - vp, VBUF,
|
||
|
(vp + w) & 0xffff);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
bp += bw;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memcpy(bp, VBUF + vp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
uchar *bp = b;
|
||
|
uchar *vp;
|
||
|
int i;
|
||
|
ASSIGNVP8(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
uchar *endoflinebp = bp + w;
|
||
|
while (bp < endoflinebp - 3) {
|
||
|
unsigned int c4 = *(unsigned int *) bp;
|
||
|
if (c4 & 0xff)
|
||
|
*vp = (uchar) c4;
|
||
|
c4 >>= 8;
|
||
|
if (c4 & 0xff)
|
||
|
*(vp + 1) = (uchar) c4;
|
||
|
c4 >>= 8;
|
||
|
if (c4 & 0xff)
|
||
|
*(vp + 2) = (uchar) c4;
|
||
|
c4 >>= 8;
|
||
|
if (c4 & 0xff)
|
||
|
*(vp + 3) = (uchar) c4;
|
||
|
bp += 4;
|
||
|
vp += 4;
|
||
|
}
|
||
|
while (bp < endoflinebp) {
|
||
|
uchar c = *bp;
|
||
|
if (c)
|
||
|
*vp = c;
|
||
|
bp++;
|
||
|
vp++;
|
||
|
}
|
||
|
vp += BYTEWIDTH - w;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8_putbox(x, y, w, h, b + yo * ow + xo, ow); /* inlined */
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8p_putbox(x, y, w, h, b + yo * ow + xo, ow); /* inlined */
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8p_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
char *svp, *dvp;
|
||
|
/* I hope this works now. */
|
||
|
if (y1 >= y2) {
|
||
|
if (y1 == y2 && x2 >= x1) { /* tricky */
|
||
|
int i;
|
||
|
if (x1 == x2)
|
||
|
return;
|
||
|
/* use a temporary buffer to store a line */
|
||
|
/* using reversed movs would be much faster */
|
||
|
ASSIGNVP8(x1, y1, svp);
|
||
|
ASSIGNVP8(x2, y2, dvp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
uchar linebuf[MAXBYTEWIDTH];
|
||
|
__memcpy(linebuf, svp, w);
|
||
|
__memcpy(dvp, linebuf, w);
|
||
|
svp += BYTEWIDTH;
|
||
|
dvp += BYTEWIDTH;
|
||
|
}
|
||
|
} else { /* copy from top to bottom */
|
||
|
int i;
|
||
|
ASSIGNVP8(x1, y1, svp);
|
||
|
ASSIGNVP8(x2, y2, dvp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(dvp, svp, w);
|
||
|
svp += BYTEWIDTH;
|
||
|
dvp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
} else { /* copy from bottom to top */
|
||
|
int i;
|
||
|
ASSIGNVP8(x1, y1 + h, svp);
|
||
|
ASSIGNVP8(x2, y2 + h, dvp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
svp -= BYTEWIDTH;
|
||
|
dvp -= BYTEWIDTH;
|
||
|
__memcpy(dvp, svp, w);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8a_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
vga_accel(ACCEL_SCREENCOPY, x1, y1, x2, y2, w, h);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Two bytes per pixel graphics primitives */
|
||
|
|
||
|
#define ASSIGNVP16(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 2;
|
||
|
#define ASSIGNVPOFFSET16(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 2;
|
||
|
|
||
|
void __svgalib_driver16_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
*(unsigned short *) vp = c;
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET16(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
*(unsigned short *) (VBUF + (vp & 0xffff)) = c;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver16_getpixel(int x, int y)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
return *(unsigned short *) vp;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver16p_getpixel(int x, int y)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET16(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
return *(unsigned short *) (VBUF + (vp & 0xffff));
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP16(x1, y, vp);
|
||
|
__memset2(vp, c, x2 - x1 + 1);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
char *rvp;
|
||
|
int l;
|
||
|
int chunksize, page;
|
||
|
ASSIGNVPOFFSET16(x1, y, vp);
|
||
|
SETWRITEPAGED(vp, rvp, chunksize, page);
|
||
|
l = (x2 - x1 + 1) * 2;
|
||
|
if (l <= chunksize)
|
||
|
__memset2(rvp, c, l / 2);
|
||
|
else {
|
||
|
__memset2(rvp, c, chunksize / 2);
|
||
|
vga_setpage(page + 1);
|
||
|
__memset2(VBUF, c, (l - chunksize) / 2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
int i;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memset2(vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
int page;
|
||
|
int i;
|
||
|
ASSIGNVPOFFSET16(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w * 2 > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
__memset2(VBUF + vp, c, (0x10000 - vp) / 2);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memset2(VBUF, c, ((vp + w * 2) & 0xffff) / 2);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memset2(VBUF + vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
bp = b;
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(vp, bp, w * 2);
|
||
|
bp += bw * 2;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8p_putbox(x * 2, y, w * 2, h, b, bw * 2);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
bp = b;
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(bp, vp, w * 2);
|
||
|
bp += bw * 2;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16p_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8p_getbox(x * 2, y, w * 2, h, b, bw * 2);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
uchar *bp = b;
|
||
|
uchar *vp;
|
||
|
int i;
|
||
|
ASSIGNVP16(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
uchar *endoflinebp = bp + w * 2;
|
||
|
while (bp < endoflinebp - 7) {
|
||
|
unsigned c2 = *(unsigned *) bp;
|
||
|
if (c2 & 0xffff)
|
||
|
*(ushort *) vp = (ushort) c2;
|
||
|
c2 >>= 16;
|
||
|
if (c2 & 0xffff)
|
||
|
*(ushort *) (vp + 2) = (ushort) c2;
|
||
|
c2 = *(unsigned *) (bp + 4);
|
||
|
if (c2 & 0xffff)
|
||
|
*(ushort *) (vp + 4) = (ushort) c2;
|
||
|
c2 >>= 16;
|
||
|
if (c2 & 0xffff)
|
||
|
*(ushort *) (vp + 6) = (ushort) c2;
|
||
|
bp += 8;
|
||
|
vp += 8;
|
||
|
}
|
||
|
while (bp < endoflinebp) {
|
||
|
ushort c = *(ushort *) bp;
|
||
|
if (c)
|
||
|
*(ushort *) vp = c;
|
||
|
bp += 2;
|
||
|
vp += 2;
|
||
|
}
|
||
|
vp += BYTEWIDTH - w * 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
|
||
|
/* inlined */
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16p_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver8p_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver16_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16p_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver16p_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver16_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
__svgalib_driver8_copybox(x1 * 2, y1, w * 2, h, x2 * 2, y2);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16a_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
int svp, dvp;
|
||
|
ASSIGNVPOFFSET16(x1, y1, svp);
|
||
|
ASSIGNVPOFFSET16(x2, y2, dvp);
|
||
|
vga_bitblt(svp, dvp, w * 2, h, BYTEWIDTH);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Three bytes per pixel graphics primitives */
|
||
|
|
||
|
#define ASSIGNVP24(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 3;
|
||
|
#define ASSIGNVPOFFSET24(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 3;
|
||
|
#define RGBEQUAL(c) ((c & 0xff) == ((c >> 8) & 0xff) && \
|
||
|
(c & 0xff) == ((c >> 16) & 0xff))
|
||
|
|
||
|
void __svgalib_driver24_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
*(unsigned short *) vp = c;
|
||
|
*(unsigned char *) (vp + 2) = c >> 16;
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24p_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
int vp, vpo;
|
||
|
char *vbuf;
|
||
|
int page;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVPOFFSET24(x, y, vp);
|
||
|
vbuf = VBUF;
|
||
|
page = vp >> 16;
|
||
|
vga_setpage(page);
|
||
|
vpo = vp & 0xffff;
|
||
|
if (vpo <= 0xfffd) {
|
||
|
*(unsigned short *) (vbuf + vpo) = c;
|
||
|
*(unsigned char *) (vbuf + vpo + 2) = c >> 16;
|
||
|
} else if (vpo == 0xfffe) {
|
||
|
*(unsigned short *) (vbuf + 0xfffe) = c;
|
||
|
vga_setpage(page + 1);
|
||
|
*(unsigned char *) vbuf = c >> 16;
|
||
|
} else { /* vpo == 0xffff */
|
||
|
*(unsigned char *) (vbuf + 0xffff) = c;
|
||
|
vga_setpage(page + 1);
|
||
|
*(unsigned short *) vbuf = c >> 8;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver24_getpixel(int x, int y)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
return RGB2BGR(*(unsigned short *) vp + (*(unsigned char *) (vp + 2) << 16));
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver24p_getpixel(int x, int y)
|
||
|
{
|
||
|
int vp, vpo;
|
||
|
char *vbuf;
|
||
|
int page;
|
||
|
ASSIGNVPOFFSET24(x, y, vp);
|
||
|
vbuf = VBUF;
|
||
|
page = vp >> 16;
|
||
|
vga_setpage(page);
|
||
|
vpo = vp & 0xffff;
|
||
|
if (vpo <= 0xfffd)
|
||
|
return RGB2BGR(*(unsigned short *) (vbuf + vpo) +
|
||
|
(*(unsigned char *) (vbuf + vpo + 2) << 16));
|
||
|
else if (vpo == 0xfffe) {
|
||
|
int c;
|
||
|
c = *(unsigned short *) (vbuf + 0xfffe);
|
||
|
vga_setpage(page + 1);
|
||
|
return RGB2BGR((*(unsigned char *) vbuf << 16) + c);
|
||
|
} else { /* vpo == 0xffff */
|
||
|
int c;
|
||
|
c = *(unsigned char *) (vbuf + 0xffff);
|
||
|
vga_setpage(page + 1);
|
||
|
return RGB2BGR((*(unsigned short *) vbuf << 8) + c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVP24(x1, y, vp);
|
||
|
if (RGBEQUAL(c))
|
||
|
__memset(vp, c, (x2 - x1 + 1) * 3);
|
||
|
else
|
||
|
__memset3(vp, c, x2 - x1 + 1);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24p_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
char *rvp;
|
||
|
int l;
|
||
|
int chunksize, page;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVPOFFSET24(x1, y, vp);
|
||
|
SETWRITEPAGED(vp, rvp, chunksize, page);
|
||
|
l = (x2 - x1 + 1) * 3;
|
||
|
if (l <= chunksize)
|
||
|
__memset3(rvp, c, l / 3);
|
||
|
else {
|
||
|
int n, m, o;
|
||
|
n = chunksize / 3;
|
||
|
m = chunksize % 3;
|
||
|
__memset3(rvp, c, n);
|
||
|
/* Handle page break within pixel. */
|
||
|
if (m >= 1)
|
||
|
*(rvp + n * 3) = c;
|
||
|
if (m == 2)
|
||
|
*(rvp + n * 3 + 1) = c >> 8;
|
||
|
vga_setpage(page + 1);
|
||
|
o = 0;
|
||
|
if (m == 2) {
|
||
|
*(VBUF) = c >> 16;
|
||
|
o = 1;
|
||
|
}
|
||
|
if (m == 1) {
|
||
|
*(unsigned short *) (VBUF) = c >> 8;
|
||
|
o = 2;
|
||
|
}
|
||
|
__memset3(VBUF + o, c, (l - chunksize) / 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
int i, j;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
if (RGBEQUAL(c))
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memset(vp, c, w * 3);
|
||
|
vp += BYTEWIDTH;
|
||
|
} else
|
||
|
for (j = 0; j < h; j++) {
|
||
|
__memset3(vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24p_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
int page;
|
||
|
int i;
|
||
|
c = RGB2BGR(c);
|
||
|
ASSIGNVPOFFSET24(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
if (RGBEQUAL(c)) {
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w * 3 > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* Page break within line. */
|
||
|
__memset(VBUF + vp, c, 0x10000 - vp);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memset(VBUF, c, (vp + w * 3) & 0xffff);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memset(VBUF + vp, c, w * 3);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
} else
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w * 3 > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* Page break within line. */
|
||
|
int n, m, o;
|
||
|
n = (0x10000 - vp) / 3;
|
||
|
m = (0x10000 - vp) % 3;
|
||
|
__memset3(VBUF + vp, c, n);
|
||
|
/* Handle page break within pixel. */
|
||
|
if (m >= 1)
|
||
|
*(VBUF + vp + n * 3) = c;
|
||
|
if (m == 2)
|
||
|
*(VBUF + vp + n * 3 + 1) = c >> 8;
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
o = 0;
|
||
|
if (m == 2) {
|
||
|
*(VBUF) = c >> 16;
|
||
|
o = 1;
|
||
|
}
|
||
|
if (m == 1) {
|
||
|
*(unsigned short *) (VBUF) = c >> 8;
|
||
|
o = 2;
|
||
|
}
|
||
|
__memset3(VBUF + o, c, ((vp + w * 3) & 0xffff) / 3);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memset3(VBUF + vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
bp = b;
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
for (i = 0; i < h; i++) {
|
||
|
RGB_swapped_memcpy(vp, bp, w * 3);
|
||
|
bp += bw * 3;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(vp, bp, w * 3);
|
||
|
bp += bw * 3;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void driver24_rev_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
/* extra argument width of source bitmap, so that putboxpart can use this */
|
||
|
int vp;
|
||
|
int page;
|
||
|
char *bp = b, *bp2;
|
||
|
int i, left;
|
||
|
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
left = RGB_swapped_memcpy(VBUF + vp, bp, 0x10000 - vp);
|
||
|
bp2 = bp + (0x10000 - vp - left);
|
||
|
switch (left) {
|
||
|
case 2:
|
||
|
*(VBUF + 0xFFFE) = bp2[2];
|
||
|
*(VBUF + 0xFFFF) = bp2[1];
|
||
|
break;
|
||
|
case 1:
|
||
|
*(VBUF + 0xFFFF) = bp2[2];
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
|
||
|
switch (left) {
|
||
|
case 1:
|
||
|
*(VBUF) = bp2[1];
|
||
|
*(VBUF + 1) = bp2[0];
|
||
|
left = 3 - left;
|
||
|
bp2 += 3;
|
||
|
break;
|
||
|
case 2:
|
||
|
*(VBUF) = bp2[0];
|
||
|
left = 3 - left;
|
||
|
bp2 += 3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
RGB_swapped_memcpy(VBUF + left, bp2, ((vp + w) & 0xffff) - left);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
bp += bw;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
RGB_swapped_memcpy(VBUF + vp, bp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24p_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
driver24_rev_putbox(x * 3, y, w * 3, h, b, bw * 3);
|
||
|
} else {
|
||
|
__svgalib_driver8p_putbox(x * 3, y, w * 3, h, b, bw * 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_putbox32(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
bp = b;
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__svgalib_memcpy4to3(vp, bp, w);
|
||
|
bp += bw * 4;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
char *vp; /* screen pointer */
|
||
|
char *bp; /* bitmap pointer */
|
||
|
int i;
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
bp = b;
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
for (i = 0; i < h; i++) {
|
||
|
RGB_swapped_memcpy(bp, vp, w * 3);
|
||
|
bp += bw * 3;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
} else {
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memcpy(bp, vp, w * 3);
|
||
|
bp += bw * 3;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void driver24_rev_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
/* extra argument width of source bitmap, so that putboxpart can use this */
|
||
|
int vp;
|
||
|
int page;
|
||
|
char *bp = b, *bp2;
|
||
|
int i, left;
|
||
|
|
||
|
ASSIGNVPOFFSET8(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
left = RGB_swapped_memcpy(bp, VBUF + vp, 0x10000 - vp);
|
||
|
bp2 = bp + (0x10000 - vp - left);
|
||
|
switch (left) {
|
||
|
case 2:
|
||
|
bp2[2] = *(VBUF + 0xFFFE);
|
||
|
bp2[1] = *(VBUF + 0xFFFF);
|
||
|
break;
|
||
|
case 1:
|
||
|
bp2[2] = *(VBUF + 0xFFFF);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
|
||
|
switch (left) {
|
||
|
case 1:
|
||
|
bp2[1] = *(VBUF);
|
||
|
bp2[0] = *(VBUF + 1);
|
||
|
left = 3 - left;
|
||
|
bp2 += 3;
|
||
|
break;
|
||
|
case 2:
|
||
|
bp2[0] = *(VBUF);
|
||
|
left = 3 - left;
|
||
|
bp2 += 3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
RGB_swapped_memcpy(bp2, VBUF + left, ((vp + w) & 0xffff) - left);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
bp += bw;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
RGB_swapped_memcpy(bp, VBUF + vp, w);
|
||
|
bp += bw;
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24p_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
driver24_rev_getbox(x * 3, y, w * 3, h, b, bw * 3);
|
||
|
} else {
|
||
|
__svgalib_driver8p_getbox(x * 3, y, w * 3, h, b, bw * 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
uchar *bp = b;
|
||
|
uchar *vp;
|
||
|
int i;
|
||
|
ASSIGNVP24(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
uchar *endoflinebp = bp + w * 3;
|
||
|
while (bp < endoflinebp - 11) {
|
||
|
unsigned c = RGB2BGR(*(unsigned *) bp);
|
||
|
if (c & 0xffffff) {
|
||
|
*(ushort *) vp = (ushort) c;
|
||
|
*(vp + 2) = c >> 16;
|
||
|
}
|
||
|
c = RGB2BGR(*(unsigned *) (bp + 3));
|
||
|
if (c & 0xffffff) {
|
||
|
*(ushort *) (vp + 3) = (ushort) c;
|
||
|
*(vp + 5) = c >> 16;
|
||
|
}
|
||
|
c = RGB2BGR(*(unsigned *) (bp + 6));
|
||
|
if (c & 0xffffff) {
|
||
|
*(ushort *) (vp + 6) = (ushort) c;
|
||
|
*(vp + 8) = c >> 16;
|
||
|
}
|
||
|
c = RGB2BGR(*(unsigned *) (bp + 9));
|
||
|
if (c & 0xffffff) {
|
||
|
*(ushort *) (vp + 9) = (ushort) c;
|
||
|
*(vp + 11) = c >> 16;
|
||
|
}
|
||
|
bp += 12;
|
||
|
vp += 12;
|
||
|
}
|
||
|
while (bp < endoflinebp) {
|
||
|
uint c = RGB2BGR(*(uint *) bp);
|
||
|
if (c & 0xffffff) {
|
||
|
*(ushort *) vp = (ushort) c;
|
||
|
*(vp + 2) = c >> 16;
|
||
|
}
|
||
|
bp += 3;
|
||
|
vp += 3;
|
||
|
}
|
||
|
vp += BYTEWIDTH - w * 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
/*
|
||
|
* Actually I think all this could be done by just calling __svgalib_driver24_putbox
|
||
|
* with correct args. But I'm too fearful. - Michael.
|
||
|
*/
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
__svgalib_driver24_putbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
} else {
|
||
|
__svgalib_driver8_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24p_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
if (MODEFLAGS & MODEFLAG_24BPP_REVERSED) {
|
||
|
driver24_rev_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
|
||
|
} else {
|
||
|
__svgalib_driver8p_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver24_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver24p_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver24p_getbox(x, y, w, h, b + yo * ow + xo, ow);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
__svgalib_driver8_copybox(x1 * 3, y1, w * 3, h, x2 * 3, y2);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24a_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
int svp, dvp;
|
||
|
ASSIGNVPOFFSET24(x1, y1, svp);
|
||
|
ASSIGNVPOFFSET24(x2, y2, dvp);
|
||
|
vga_bitblt(svp, dvp, w * 3, h, BYTEWIDTH);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Four bytes per pixel graphics primitives */
|
||
|
|
||
|
#define ASSIGNVP32(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 4;
|
||
|
#define ASSIGNVPOFFSET32(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 4;
|
||
|
|
||
|
void __svgalib_driver32_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP32(x, y, vp);
|
||
|
*(unsigned *) vp = c;
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32p_setpixel(int x, int y, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET32(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
*(unsigned *) (VBUF + (vp & 0xffff)) = c;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver32_getpixel(int x, int y)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP32(x, y, vp);
|
||
|
return *(unsigned *) vp;
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver32p_getpixel(int x, int y)
|
||
|
{
|
||
|
int vp;
|
||
|
ASSIGNVPOFFSET32(x, y, vp);
|
||
|
vga_setpage(vp >> 16);
|
||
|
return *(unsigned *) (VBUF + (vp & 0xffff));
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
ASSIGNVP32(x1, y, vp);
|
||
|
__memset4(vp, c, x2 - x1 + 1);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32p_hline(int x1, int y, int x2, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
char *rvp;
|
||
|
int l;
|
||
|
int chunksize, page;
|
||
|
ASSIGNVPOFFSET32(x1, y, vp);
|
||
|
SETWRITEPAGED(vp, rvp, chunksize, page);
|
||
|
l = (x2 - x1 + 1) * 4;
|
||
|
if (l <= chunksize)
|
||
|
__memset4(rvp, c, l / 4);
|
||
|
else {
|
||
|
__memset4(rvp, c, chunksize / 4);
|
||
|
vga_setpage(page + 1);
|
||
|
__memset4(VBUF, c, (l - chunksize) / 4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
char *vp;
|
||
|
int i;
|
||
|
ASSIGNVP32(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
__memset4(vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32p_fillbox(int x, int y, int w, int h, int c)
|
||
|
{
|
||
|
int vp;
|
||
|
int page;
|
||
|
int i;
|
||
|
ASSIGNVPOFFSET32(x, y, vp);
|
||
|
page = vp >> 16;
|
||
|
vp &= 0xffff;
|
||
|
vga_setpage(page);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
if (vp + w * 4 > 0x10000) {
|
||
|
if (vp >= 0x10000) {
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
vp &= 0xffff;
|
||
|
} else { /* page break within line */
|
||
|
__memset4(VBUF + vp, c, (0x10000 - vp) / 4);
|
||
|
page++;
|
||
|
vga_setpage(page);
|
||
|
__memset4(VBUF, c, ((vp + w * 4) & 0xffff) / 4);
|
||
|
vp = (vp + BYTEWIDTH) & 0xffff;
|
||
|
continue;
|
||
|
}
|
||
|
};
|
||
|
__memset4(VBUF + vp, c, w);
|
||
|
vp += BYTEWIDTH;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8_putbox(x * 4, y, w * 4, h, b, bw * 4);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32p_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8p_putbox(x * 4, y, w * 4, h, b, bw * 4);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8_getbox(x * 4, y, w * 4, h, b, bw * 4);
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32p_getbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
__svgalib_driver8p_getbox(x * 4, y, w * 4, h, b, bw * 4);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
uchar *bp = b;
|
||
|
uchar *vp;
|
||
|
int i;
|
||
|
ASSIGNVP32(x, y, vp);
|
||
|
for (i = 0; i < h; i++) {
|
||
|
uchar *endoflinebp = bp + w * 4;
|
||
|
while (bp < endoflinebp - 15) {
|
||
|
unsigned c = *(unsigned *) bp;
|
||
|
if (c)
|
||
|
*(unsigned *) vp = c;
|
||
|
c = *(unsigned *) (bp + 4);
|
||
|
if (c)
|
||
|
*(unsigned *) (vp + 4) = c;
|
||
|
c = *(unsigned *) (bp + 8);
|
||
|
if (c)
|
||
|
*(unsigned *) (vp + 8) = c;
|
||
|
c = *(unsigned *) (bp + 12);
|
||
|
if (c)
|
||
|
*(unsigned *) (vp + 12) = c;
|
||
|
bp += 16;
|
||
|
vp += 16;
|
||
|
}
|
||
|
while (bp < endoflinebp) {
|
||
|
unsigned c = *(unsigned *) bp;
|
||
|
if (c)
|
||
|
*(unsigned *) vp = c;
|
||
|
bp += 4;
|
||
|
vp += 4;
|
||
|
}
|
||
|
vp += BYTEWIDTH - w * 4;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver32_putbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
|
||
|
/* inlined */
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32p_putboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver32p_putbox(x, y, w, h, b + yo * ow * 4 + xo * 4, ow );
|
||
|
/* inlined */
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver32_getbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32p_getboxpart(int x, int y, int w, int h, int ow, int oh,
|
||
|
void *b, int xo, int yo)
|
||
|
{
|
||
|
__svgalib_driver32p_getbox(x, y, w, h, b + yo * ow * 4 + xo * 4 , ow );
|
||
|
}
|
||
|
|
||
|
INLINE void __svgalib_driver32_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
__svgalib_driver8_copybox(x1 * 4, y1, w * 4, h, x2 * 4, y2);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Planar 256 color mode graphics primitives (only putbox) */
|
||
|
|
||
|
void __svgalib_driverplanar256_nothing(void)
|
||
|
{
|
||
|
NOTIMPL("planar 256 color mode primitive");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driverplanar256_putbox(int x, int y, int w, int h, void *b, int bw)
|
||
|
{
|
||
|
if ((w & 3) != 0 || (x & 3) != 0)
|
||
|
NOTIMPL("planar 256 color mode unaligned putbox");
|
||
|
vga_copytoplanar256(b, bw, y * BYTEWIDTH + x / 4, BYTEWIDTH,
|
||
|
w, h);
|
||
|
}
|
||
|
|
||
|
void __svgalib_driverplanar16_nothing(void)
|
||
|
{
|
||
|
NOTIMPL("planar 16 color mode primitive");
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Memory primitives */
|
||
|
|
||
|
int __svgalib_driver_setread(GraphicsContext * gc, int i, void **vp)
|
||
|
{
|
||
|
if (gc->modetype == CONTEXT_PAGED) {
|
||
|
vga_setpage(i >> 16);
|
||
|
*vp = (i & 0xffff) + gc->vbuf;
|
||
|
return 0x10000 - (i & 0xffff);
|
||
|
} else {
|
||
|
*vp = gc->vbuf + i;
|
||
|
return 0x10000;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int __svgalib_driver_setwrite(GraphicsContext * gc, int i, void **vp)
|
||
|
{
|
||
|
if (gc->modetype == CONTEXT_PAGED) {
|
||
|
vga_setpage(i >> 16);
|
||
|
*vp = (i & 0xffff) + gc->vbuf;
|
||
|
return 0x10000 - (i & 0xffff);
|
||
|
} else {
|
||
|
*vp = gc->vbuf + i;
|
||
|
return 0x10000;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* Functions that are not yet implemented */
|
||
|
|
||
|
void __svgalib_driver8p_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
NOTIMPL("8-bit paged putboxmask");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver8p_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
NOTIMPL("8-bit paged copybox (bitblt)");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
NOTIMPL("16-bit paged putboxmask");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver16p_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
NOTIMPL("16-bit paged copybox");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24p_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
NOTIMPL("24-bit paged putboxmask");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver24p_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
NOTIMPL("24-bit paged copybox");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32p_putboxmask(int x, int y, int w, int h, void *b)
|
||
|
{
|
||
|
NOTIMPL("32-bit paged putboxmask");
|
||
|
}
|
||
|
|
||
|
void __svgalib_driver32p_copybox(int x1, int y1, int w, int h, int x2, int y2)
|
||
|
{
|
||
|
NOTIMPL("32-bit paged copybox");
|
||
|
}
|