📄 grlib.c
字号:
ny = __clipy1; \ } \ if (nx + nw > __clipx2) /* right adjust */ \ nw = __clipx2 - nx + 1; \ if (ny + nh > __clipy2) /* bottom adjust */ \ nh = __clipy2 - ny + 1; \void gl_fillbox(int x, int y, int w, int h, int c){ if (__clip) { if (x + w < __clipx1 || x > __clipx2) return; if (y + h < __clipy1 || y > __clipy2) return; if (x < __clipx1) { w -= __clipx1 - x; x = __clipx1; } if (y < __clipy1) { h -= __clipy1 - y; y = __clipy1; } if (x + w > __clipx2 + 1) w = __clipx2 - x + 1; if (y + h > __clipy2 + 1) h = __clipy2 - y + 1; } if (w <= 0 || h <= 0) return; fillbox(x, y, w, h, c);}void gl_putboxpart(int x, int y, int w, int h, int ow, int oh, void *b, int ox, int oy){ putboxpart(x, y, w, h, ow, oh, b, ox, oy);}void gl_putbox(int x, int y, int w, int h, void *b){ uchar *bp = b; if (w <= 0 || h <= 0) return; if (__clip) { int nx, ny, nw, nh; ADJUSTBITMAPBOX(); if (nw <= 0 || nh <= 0) return; if (nw != w || nh != h) { putboxpart(nx, ny, nw, nh, w, h, bp, nx - x, ny - y); return; } } putbox(x, y, w, h, bp, w);}static void emulate_putboxmask(int x, int y, int w, int h, void *b){ void *box; GraphicsContext gc; box = alloca(w * h * BYTESPERPIXEL); gl_getbox(x, y, w, h, box); /* does clipping */ gl_getcontext(&gc); /* save context */ /* create context that is only the box */ gl_setcontextvirtual(w, h, BYTESPERPIXEL, BITSPERPIXEL, box); gl_putboxmask(0, 0, w, h, b); gl_setcontext(&gc); /* restore context */ gl_putbox(x, y, w, h, box);}void gl_putboxmask(int x, int y, int w, int h, void *b){ if (w <= 0 || h <= 0) return; if (__clip) { if (x + w < __clipx1 || x > __clipx2) return; if (y + h < __clipy1 || y > __clipy2) return; if (x < __clipx1 || y < __clipy1 || x + w > __clipx2 + 1 || y + h > __clipy2 + 1) { /* clipping is not directly implemented */ emulate_putboxmask(x, y, w, h, b); return; } } if (MODETYPE == CONTEXT_PAGED) /* paged primitive is not implemented */ emulate_putboxmask(x, y, w, h, b); else putboxmask(x, y, w, h, b);}void gl_getbox(int x, int y, int w, int h, void *b){ if (__clip) { int nx, ny, nw, nh; ADJUSTBITMAPBOX(); if (nw <= 0 || nh <= 0) return; if (nw != w || nh != h) { getboxpart(nx, ny, nw, nh, w, h, b, nx - x, ny - y); return; } } getbox(x, y, w, h, b, w);}void gl_copybox(int x1, int y1, int w, int h, int x2, int y2){/* Doesn't handle clipping. */ if (MODETYPE == CONTEXT_PAGED) { /* Paged primitive is not implemented. */ void *box; box = alloca(w * h * BYTESPERPIXEL); getbox(x1, y1, w, h, box, w); putbox(x2, y2, w, h, box, w); return; } copybox(x1, y1, w, h, x2, y2);}/* Miscellaneous functions */void gl_clearscreen(int c){ gl_fillbox(0, 0, WIDTH, HEIGHT, c);}int gl_rgbcolor(int r, int g, int b){ unsigned v; switch (BITSPERPIXEL) { case 8: /* assumes RGB palette at index 0-255 */ /* bits 0-2 = blue (3 bits) */ /* 3-5 = green (3 bits) */ /* 6-7 = red (2 bits) */ return (r & 0xc0) + ((g & 0xe0) >> 2) + (b >> 5); case 24: case 32: v = (r << 16) + (g << 8) + b; if (MODEFLAGS & MODEFLAG_32BPP_SHIFT8) return v << 8; return v; case 15: return ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + (b >> 3); case 16: return ((r & 0xf8) << 8) + ((g & 0xfc) << 3) + (b >> 3); case 4: /* Now this is real fun. Map to standard EGA palette. */ v = 0; if (b >= 64) v += 1; if (g >= 64) v += 2; if (r >= 64) v += 4; if (b >= 192 || g >= 192 || r >= 192) v += 8; return v; } return -1;}void gl_setpixelrgb(int x, int y, int r, int g, int b){/* Color components range from 0 to 255 */ if (__clip && outside(x, y)) return; setpixel(x, y, gl_rgbcolor(r, g, b));}void gl_getpixelrgb(int x, int y, int *r, int *g, int *b){ unsigned c; if (__clip && outside(x, y)) { *r = *g = *b = -1; return; } c = getpixel(x, y); switch (BITSPERPIXEL) { case 8: *b = (c & (1 + 2 + 4)) << 5; /* bits 0-2 */ *g = (c & (8 + 16 + 32)) << 2; /* bits 3-5 */ *r = (c & (64 + 128)); /* bits 6-7 */ break; case 32: if (MODEFLAGS & MODEFLAG_32BPP_SHIFT8) { *b = (c & 0xff00) >> 8; *g = (c & 0xff0000) >> 16; *r = c >> 24; break; } case 24: *b = c & 0xff; *g = (c & 0xff00) >> 8; *r = c >> 16; break; case 15: *b = (c & (1 + 2 + 4 + 8 + 16)) << 3; *g = (c & (32 + 64 + 128 + 256 + 512)) >> 2; *r = (c & (1024 + 2048 + 4096 + 8192 + 16384)) >> 7; break; case 16: *b = (c & (1 + 2 + 4 + 8 + 16)) << 3; *g = (c & (32 + 64 + 128 + 256 + 512 + 1024)) >> 3; *r = (c & (2048 + 4096 + 8192 + 16384 + 32768)) >> 8; break; case 4: *b = (c & 1) * ((c & 8) ? 255 : 128); *g = (c & 2) * ((c & 8) ? 255 : 128); *r = (c & 4) * ((c & 8) ? 255 : 128); break; }}void gl_setdisplaystart(int x, int y){ vga_setdisplaystart(y * BYTEWIDTH + x * BYTESPERPIXEL);}/* Screen copying */void gl_setscreenoffset(int o){ screenoffset = o;}int gl_enablepageflipping(GraphicsContext * gc){ if (gc->modeflags & MODEFLAG_PAGEFLIPPING_CAPABLE) { gc->modeflags |= MODEFLAG_PAGEFLIPPING_ENABLED; } if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_CAPABLE) { gc->modeflags &= ~(MODEFLAG_PAGEFLIPPING_ENABLED); gc->modeflags |= MODEFLAG_TRIPLEBUFFERING_ENABLED; } gc->flippage = 0; if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_ENABLED) return 3; if (gc->modeflags & MODEFLAG_PAGEFLIPPING_ENABLED) return 2; return 0;}void gl_copyscreen(GraphicsContext * gc){ int size; void *svp, *dvp; if (gc->modeflags & MODEFLAG_PAGEFLIPPING_ENABLED) gc->flippage ^= 1; if (gc->modeflags & MODEFLAG_TRIPLEBUFFERING_ENABLED) gc->flippage = (gc->flippage + 1) % 3; if (gc->modeflags & (MODEFLAG_PAGEFLIPPING_ENABLED | MODEFLAG_TRIPLEBUFFERING_ENABLED)) { /* Calculate screen offset in bytes. */ screenoffset = gc->bytewidth * HEIGHT * gc->flippage; if (gc->modeflags & MODEFLAG_FLIPPAGE_BANKALIGNED) screenoffset = ((screenoffset + 0xffff) & ~0xffff); } if (gc->modetype == CONTEXT_MODEX) { vga_copytoplanar256(VBUF, BYTEWIDTH, screenoffset / 4, gc->bytewidth / 4, WIDTH, HEIGHT); goto end; } if (gc->modetype == CONTEXT_PLANAR16) { if (WIDTH == 1024 && HEIGHT >= 512 && ((screenoffset / 8) & 0xffff) == 0) { /* Kludge to allow 1024x768x16 with page flipping. */ int page; page = (screenoffset / 8) >> 16; vga_setpage(page); vga_copytoplanar16(VBUF, BYTEWIDTH, 0, gc->bytewidth / 8, WIDTH, 512); vga_setpage(page + 1); vga_copytoplanar16(VBUF + WIDTH * 512, BYTEWIDTH, 0, gc->bytewidth / 8, WIDTH, HEIGHT - 512); return; } if (WIDTH * HEIGHT >= 512 * 1024) /* We don't handle banking. */ return; vga_copytoplanar16(VBUF, BYTEWIDTH, screenoffset / 8, gc->bytewidth / 8, WIDTH, HEIGHT); goto end; } if (BYTESPERPIXEL == 4 && gc->bytesperpixel == 3) { /* Special case. */ int soffset, doffset; if (BYTEWIDTH / 4 != gc->bytewidth / 3) { /* Even more special case for physical truecolor */ /* modes that have extra scanline padding. */ /* This has the effect of slowing down */ /* '3d' in some truecolor modes on ATI mach32. */ gl_copyboxtocontext(0, 0, WIDTH, HEIGHT, gc, 0, 0); goto end; } soffset = 0; doffset = screenoffset; size = WIDTH * HEIGHT; while (soffset / 4 < size) { int schunk, dchunk; int count; schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp); dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp); if (dchunk == 1) { /* One byte left in segment. */ int pix; pix = *(unsigned *) svp; /* 32-bit pixel */ *(unsigned char *) dvp = pix; dchunk = __svgalib_driver_setwrite(gc, doffset + 1, &dvp); *(unsigned short *) dvp = pix >> 8; count = 1; /* 1 pixel handled. */ } else if (dchunk == 2) { /* Two bytes left. */ int pix; pix = *(unsigned *) svp; /* 32-bit pixel */ *(unsigned short *) dvp = pix; dchunk = __svgalib_driver_setwrite(gc, doffset + 2, &dvp); *(unsigned char *) dvp = pix >> 16; count = 1; /* 1 pixel handled. */ } else { count = min(min(schunk / 4, dchunk / 3), size - (soffset / 4)); __svgalib_memcpy4to3(dvp, svp, count); } soffset += count * 4; doffset += count * 3; } goto end; } if (BYTESPERPIXEL == 4 && gc->bytesperpixel == 4 && (gc->modeflags & MODEFLAG_32BPP_SHIFT8)) { int soffset = 0; int doffset = screenoffset; size = SCREENSIZE(__currentcontext); while (soffset < size) { int schunk, dchunk; int count; schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp); dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp); count = min(min(schunk, dchunk), (size - soffset)); __svgalib_memcpy32shift8(dvp, svp, count / 4); soffset += count; doffset += count; } } else { int soffset = 0; int doffset = screenoffset; size = SCREENSIZE(__currentcontext); while (soffset < size) { int schunk, dchunk; int count; schunk = __svgalib_driver_setread(&__currentcontext, soffset, &svp); dchunk = __svgalib_driver_setwrite(gc, doffset, &dvp); count = min(min(schunk, dchunk), (size - soffset)); __memcpy(dvp, svp, count); soffset += count; doffset += count; } } end: if (gc->modeflags & (MODEFLAG_PAGEFLIPPING_ENABLED | MODEFLAG_TRIPLEBUFFERING_ENABLED)) { GraphicsContext save; /* setdisplaystart will use BYTEWIDTH of the virtual screen, */ /* which is what we want since vga_setdisplaystart is */ /* defined in terms of pixel offset (except for hicolor */ /* modes, which are defined in terms of bytes). */ gl_getcontext(&save); gl_setcontext(gc); if (gc->modeflags & MODEFLAG_FLIPPAGE_BANKALIGNED) vga_setdisplaystart(screenoffset); else gl_setdisplaystart(0, gc->height * gc->flippage); gl_setcontext(&save); /* For page flipping, it might be appropriate to add a */ /* waitverticalretrace here. */ } screenoffset = 0;}void gl_copyboxtocontext(int x1, int y1, int w, int h, GraphicsContext * gc, int x2, int y2){/* This is now reasonably efficient if clipping is not enabled. */ void *buf; GraphicsContext save; gl_getcontext(&save); if ((MODETYPE == CONTEXT_LINEAR || MODETYPE == CONTEXT_VIRTUAL) && (BYTESPERPIXEL == gc->bytesperpixel) && !__clip && !gc->clip) {#ifdef DLL_CONTEXT_SHADOW __currentcontext = *gc;#else gl_setcontext(gc);#endif/* * Note: Using save.bytewidth / BYTESPERPIXEL is probably not an optimal hack here. * it would be better to transfer save.bytewidth to putbox as it is what is really * used there. However, putbox is used all over interpreting the last entry as a * pixel count, so we keep it this way to avoid problems if some other place not * updated by accident. */ putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, save.vbuf + y1 * save.bytewidth + x1 * BYTESPERPIXEL, save.bytewidth / BYTESPERPIXEL); goto end; } buf = alloca(w * h * BYTESPERPIXEL); gl_getbox(x1, y1, w, h, buf);#ifdef DLL_CONTEXT_SHADOW __currentcontext = *gc;#else gl_setcontext(gc);#endif if (save.bytesperpixel == 4 && gc->bytesperpixel == 3) { /* Special case conversion from 32-bit virtual screen to */ /* 24-bit truecolor framebuffer. */ if (gc->modetype == CONTEXT_PAGED || gc->clip) { /* For paged modes or clipping, use another buffer. */ void *buf2; buf2 = alloca(w * h * 3); __svgalib_memcpy4to3(buf2, buf, w * h); gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf2); } else /* No clipping, linear. */ __svgalib_driver24_putbox32(x2, y2, w, h, buf, w); } else /* Contexts assumed to have same pixel size. */ gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf); end:#ifdef DLL_CONTEXT_SHADOW __currentcontext = save;#else gl_setcontext(&save);#endif}void gl_copyboxfromcontext(GraphicsContext * gc, int x1, int y1, int w, int h, int x2, int y2){ void *buf; GraphicsContext save; if ((gc->modetype == CONTEXT_LINEAR || gc->modetype == CONTEXT_VIRTUAL) && (BYTESPERPIXEL == gc->bytesperpixel) && !__clip && !gc->clip) {/* * see above on gc->bytewidth / BYTESPERPIXEL. */ putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, gc->vbuf + y1 * gc->bytewidth + x1 * BYTESPERPIXEL, gc->bytewidth / BYTESPERPIXEL); return; } gl_getcontext(&save);#ifdef DLL_CONTEXT_SHADOW __currentcontext = *gc;#else gl_setcontext(gc);#endif buf = alloca(w * h * BYTESPERPIXEL); gl_getbox(x1, y1, w, h, buf);#ifdef DLL_CONTEXT_SHADOW __currentcontext = save;#else gl_setcontext(&save);#endif if (gc->bytesperpixel == 4 && save.bytesperpixel == 3) { /* Special case conversion from 32-bit virtual screen to */ /* 24-bit truecolor framebuffer. */ if (save.modetype == CONTEXT_PAGED || save.clip) { /* For paged modes or clipping, use another buffer. */ void *buf2; buf2 = alloca(w * h * 3); __svgalib_memcpy4to3(buf2, buf, w * h); gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf2); } else /* No clipping, linear. */ __svgalib_driver24_putbox32(x2, y2, w, h, buf, w); } else /* Contexts assumed to have same pixel size. */ gl_putbox(x2, y2 + screenoffset / BYTEWIDTH, w, h, buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -