📄 grlib.c~
字号:
/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer *//* grlib.c Main module */#include <stdlib.h>#include <vga.h>#include "inlstring.h" /* include inline string operations */#include "vgagl.h"#include "def.h"#include "driver.h"/* Global variables */#ifdef DLL_CONTEXT_SHADOW/* The current context variable is shadowed in a read-only variable for *//* external use. */GraphicsContext __currentcontext; /* Internal current context. */GraphicsContext currentcontext; /* Copy for external use. */#elseGraphicsContext currentcontext;#endifvoid (*__svgalib_nonaccel_fillbox)(int, int, int, int, int);static int screenoffset = 0; /* Used by copy(box)toscreen. *//* Framebuffer function pointers */static framebufferfunctions ff8 ={ __svgalib_driver8_setpixel, __svgalib_driver8_getpixel, __svgalib_driver8_hline, __svgalib_driver8_fillbox, __svgalib_driver8_putbox, __svgalib_driver8_getbox, __svgalib_driver8_putboxmask, __svgalib_driver8_putboxpart, __svgalib_driver8_getboxpart, __svgalib_driver8_copybox};static framebufferfunctions ff16 ={ __svgalib_driver16_setpixel, __svgalib_driver16_getpixel, __svgalib_driver16_hline, __svgalib_driver16_fillbox, __svgalib_driver16_putbox, __svgalib_driver16_getbox, __svgalib_driver16_putboxmask, __svgalib_driver16_putboxpart, __svgalib_driver16_getboxpart, __svgalib_driver16_copybox};static framebufferfunctions ff24 ={ __svgalib_driver24_setpixel, __svgalib_driver24_getpixel, __svgalib_driver24_hline, __svgalib_driver24_fillbox, __svgalib_driver24_putbox, __svgalib_driver24_getbox, __svgalib_driver24_putboxmask, __svgalib_driver24_putboxpart, __svgalib_driver24_getboxpart, __svgalib_driver24_copybox};static framebufferfunctions ff32 ={ __svgalib_driver32_setpixel, __svgalib_driver32_getpixel, __svgalib_driver32_hline, __svgalib_driver32_fillbox, __svgalib_driver32_putbox, __svgalib_driver32_getbox, __svgalib_driver32_putboxmask, __svgalib_driver32_putboxpart, __svgalib_driver32_getboxpart, __svgalib_driver32_copybox};static framebufferfunctions ff8paged ={ __svgalib_driver8p_setpixel, __svgalib_driver8p_getpixel, __svgalib_driver8p_hline, __svgalib_driver8p_fillbox, __svgalib_driver8p_putbox, __svgalib_driver8p_getbox, __svgalib_driver8p_putboxmask, __svgalib_driver8p_putboxpart, __svgalib_driver8p_getboxpart, __svgalib_driver8p_copybox};static framebufferfunctions ff16paged ={ __svgalib_driver16p_setpixel, __svgalib_driver16p_getpixel, __svgalib_driver16p_hline, __svgalib_driver16p_fillbox, __svgalib_driver16p_putbox, __svgalib_driver16p_getbox, __svgalib_driver16p_putboxmask, __svgalib_driver16p_putboxpart, __svgalib_driver16p_getboxpart, __svgalib_driver16p_copybox};static framebufferfunctions ff24paged ={ __svgalib_driver24p_setpixel, __svgalib_driver24p_getpixel, __svgalib_driver24p_hline, __svgalib_driver24p_fillbox, __svgalib_driver24p_putbox, __svgalib_driver24p_getbox, __svgalib_driver24p_putboxmask, __svgalib_driver24p_putboxpart, __svgalib_driver24p_getboxpart, __svgalib_driver24p_copybox};static framebufferfunctions ff32paged ={ __svgalib_driver32p_setpixel, __svgalib_driver32p_getpixel, __svgalib_driver32p_hline, __svgalib_driver32p_fillbox, __svgalib_driver32p_putbox, __svgalib_driver32p_getbox, __svgalib_driver32p_putboxmask, __svgalib_driver32p_putboxpart, __svgalib_driver32p_getboxpart, __svgalib_driver32p_copybox};static framebufferfunctions ffplanar256 ={ (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, __svgalib_driverplanar256_putbox, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing, (void *) __svgalib_driverplanar256_nothing,};#if 0 /* Not yet used */static framebufferfunctions ffplanar16 ={ (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing, (void *) __svgalib_driverplanar16_nothing,};#endif/* Initialization and graphics contexts */#define SCREENSIZE(gc) ((gc).bytewidth * (gc).height)static int colorbits(int c){ switch (c) { default: case 256: return 8; case 32768: return 15; case 65536: return 16; case 256 * 65536: return 24; }}int gl_setcontextvga(int m){ framebufferfunctions *ff; vga_modeinfo *modeinfo; int accelfuncs; if (!vga_hasmode(m)) return -1; modeinfo = vga_getmodeinfo(m); /* Set graphics context */ WIDTH = modeinfo->width; HEIGHT = modeinfo->height; BYTESPERPIXEL = modeinfo->bytesperpixel; COLORS = modeinfo->colors; BITSPERPIXEL = colorbits(COLORS); BYTEWIDTH = modeinfo->linewidth; VBUF = vga_getgraphmem(); MODEFLAGS = 0; __clip = 0; ff = &(__currentcontext.ff); if (modeinfo->flags & IS_MODEX) { /* Pretend it's a regular (linear) context. */ BYTESPERPIXEL = 1; BYTEWIDTH *= 4; MODETYPE = CONTEXT_MODEX; if (BYTEWIDTH * HEIGHT * 2 <= 256 * 1024) MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE; if (BYTEWIDTH * HEIGHT * 3 <= 256 * 1024) MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE; __currentcontext.ff = ffplanar256; } else if (modeinfo->colors == 16) { /* Pretend it's a regular one byte per pixel context. */ BYTESPERPIXEL = 1; BYTEWIDTH *= 8; MODETYPE = CONTEXT_PLANAR16; if (BYTEWIDTH * HEIGHT <= 256 * 1024) MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE; if (BYTEWIDTH * HEIGHT * 3 / 2 <= 256 * 1024) MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE; } else if ((m == G320x200x256 && modeinfo->maxpixels <= 65536) || (modeinfo->flags & IS_LINEAR)#if 0 /* svgalib doesn't VT-switch correctly with linear addressing. */ || ((modeinfo->flags & CAPABLE_LINEAR) /* Creepy. Try linear addressing only if the mode is set. */ && vga_getcurrentmode() == m && (vga_setlinearaddressing() != -1))#endif ) { /* No banking. */ /* Get get the fb address in case we set linear addressing. */ VBUF = vga_getgraphmem(); MODETYPE = CONTEXT_LINEAR; if (modeinfo->maxpixels >= WIDTH * HEIGHT * 2) MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE; if (modeinfo->maxpixels >= WIDTH * HEIGHT * 3) MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE; switch (BYTESPERPIXEL) { case 1: __currentcontext.ff = ff8; break; case 2: __currentcontext.ff = ff16; break; case 3: __currentcontext.ff = ff24; break; case 4: __currentcontext.ff = ff32; break; } if (modeinfo->flags & RGB_MISORDERED) MODEFLAGS |= MODEFLAG_32BPP_SHIFT8; } else { /* Banked mode. */ MODETYPE = CONTEXT_PAGED; if (modeinfo->maxpixels >= WIDTH * HEIGHT * 2) MODEFLAGS |= MODEFLAG_PAGEFLIPPING_CAPABLE; if (modeinfo->maxpixels >= WIDTH * HEIGHT * 3) MODEFLAGS |= MODEFLAG_TRIPLEBUFFERING_CAPABLE; if ((modeinfo->startaddressrange & 0x1ffff) == 0x10000) { /* This hack is required for 320x200x256 page flipping */ /* on Trident, which doesn't work with bank boundary */ /* within the second page. */ MODEFLAGS |= MODEFLAG_FLIPPAGE_BANKALIGNED; } switch (BYTESPERPIXEL) { case 1: __currentcontext.ff = ff8paged; break; case 2: __currentcontext.ff = ff16paged; break; case 3: __currentcontext.ff = ff24paged; break; case 4: __currentcontext.ff = ff32paged; break; } if (modeinfo->flags & RGB_MISORDERED) MODEFLAGS |= MODEFLAG_32BPP_SHIFT8; } if (vga_getcurrentmode() == m) { accelfuncs = vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL); __svgalib_nonaccel_fillbox = __currentcontext.ff.driver_fillbox_func; if (accelfuncs & ACCELFLAG_FILLBOX) __currentcontext.ff.driver_fillbox_func = __svgalib_driver8a_fillbox; if (accelfuncs & ACCELFLAG_SCREENCOPY) __currentcontext.ff.driver_copybox_func = __svgalib_driver8a_copybox; }#ifdef DLL_CONTEXT_SHADOW currentcontext = __currentcontext;#endif return 0;}int gl_setcontextvgavirtual(int m){ vga_modeinfo *modeinfo; if (!vga_hasmode(m)) return -1; modeinfo = vga_getmodeinfo(m); /* Set graphics context */ WIDTH = modeinfo->width; HEIGHT = modeinfo->height; if (modeinfo->flags & IS_MODEX) { /* Use a regular virtual screen for planar 256 color modes. */ BYTESPERPIXEL = 1; BYTEWIDTH = modeinfo->linewidth * 4; } else if (modeinfo->colors == 16) { /* Use a regular one byte per pixel virtual screen for */ /* planar 16 color modes. */ BYTESPERPIXEL = 1; BYTEWIDTH = modeinfo->linewidth * 8; } else { BYTESPERPIXEL = modeinfo->bytesperpixel; BYTEWIDTH = modeinfo->linewidth; } COLORS = modeinfo->colors; BITSPERPIXEL = colorbits(COLORS); VBUF = malloc(SCREENSIZE(__currentcontext)); MODETYPE = CONTEXT_VIRTUAL; MODEFLAGS = 0; __clip = 0; switch (BYTESPERPIXEL) { case 1: __currentcontext.ff = ff8; break; case 2: __currentcontext.ff = ff16; break; case 3: __currentcontext.ff = ff24; break; case 4: __currentcontext.ff = ff32; break; }#ifdef DLL_CONTEXT_SHADOW currentcontext = __currentcontext;#endif return 0;}void gl_setcontextvirtual(int w, int h, int bpp, int bitspp, void *v){ WIDTH = w; HEIGHT = h; BYTESPERPIXEL = bpp; BITSPERPIXEL = bitspp; COLORS = 1 << bitspp; BYTEWIDTH = WIDTH * BYTESPERPIXEL; VBUF = v; MODETYPE = CONTEXT_VIRTUAL; MODEFLAGS = 0; switch (BYTESPERPIXEL) { case 1: __currentcontext.ff = ff8; break; case 2: __currentcontext.ff = ff16; break; case 3: __currentcontext.ff = ff24; break; case 4: __currentcontext.ff = ff32; break; } __clip = 0;#ifdef DLL_CONTEXT_SHADOW currentcontext = __currentcontext;#endif}GraphicsContext * gl_allocatecontext(){ return malloc(sizeof(GraphicsContext));}void gl_setcontext(GraphicsContext * gc){ __currentcontext = *gc;#ifdef DLL_CONTEXT_SHADOW currentcontext = *gc;#endif}void gl_getcontext(GraphicsContext * gc){ *gc = __currentcontext;}void gl_freecontext(GraphicsContext * gc){ if (gc->modetype == CONTEXT_VIRTUAL) free(gc->vbuf);}void gl_setcontextwidth(int w){ __currentcontext.width = currentcontext.width = w; __currentcontext.bytewidth = currentcontext.bytewidth = w * BYTESPERPIXEL;}void gl_setcontextheight(int h){ __currentcontext.height = currentcontext.height = h;}/* Clipping */void gl_setclippingwindow(int x1, int y1, int x2, int y2){ __clip = 1; __clipx1 = x1; __clipy1 = y1; __clipx2 = x2; __clipy2 = y2;}void gl_enableclipping(){ __clip = 1; __clipx1 = 0; __clipy1 = 0; __clipx2 = WIDTH - 1; __clipy2 = HEIGHT - 1;}void gl_disableclipping(){ __clip = 0;}/* Primitive functions */void gl_setpixel(int x, int y, int c){ if (__clip && outside(x, y)) return; setpixel(x, y, c);}int gl_getpixel(int x, int y){ if (__clip && outside(x, y)) return -1; return getpixel(x, y);}void gl_hline(int x1, int y, int x2, int c){ if (__clip) { if (y_outside(y)) return; clipxleft(x1); clipxright(x2); } if (x1 > x2) return; hline(x1, y, x2, c);}#define ADJUSTBITMAPBOX() \ nw = w; nh = h; nx = x; ny = y; \ if (nx + nw < __clipx1 || nx > __clipx2) \ return; \ if (ny + nh < __clipy1 || ny > __clipy2) \ return; \ if (nx < __clipx1) { /* left adjust */ \ nw += nx - __clipx1; \ nx = __clipx1; \ } \ if (ny < __clipy1) { /* top adjust */ \ nh += ny - __clipy1; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -