📄 driver.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 __alpha__ 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){#ifdef __alpha__ vga_setcolor(c); vga_drawpixel(x, y);#else char *vp; ASSIGNVP8(x, y, vp); *vp = c;#endif}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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -