📄 scr_svga.c
字号:
/*
* Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
*
* Microwindows Screen Driver using SVGA Library
*
* This driver requires the following SVGA entry points:
* vga_init, vga_setmode,
* vga_drawpixel, vga_getpixel,
* vga_setegacolor, vga_drawline,
* vga_getscansegment, vga_drawscansegment
*
* All graphics drawing primitives are based on top of these functions.
*/
/*#define NDEBUG*/
#include <assert.h>
#include <stdio.h>
#include <vga.h>
#include "device.h"
#include "genfont.h"
#include "genmem.h"
#define MAXLINELEN 800 /* max line byte/pixel length*/
/* specific driver entry points*/
static PSD SVGA_open(PSD psd);
static void SVGA_close(PSD psd);
static void SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi);
static void SVGA_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);
static void SVGA_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);
static MWPIXELVAL SVGA_readpixel(PSD psd,MWCOORD x, MWCOORD y);
static void SVGA_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);
static void SVGA_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);
static void SVGA_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2,
MWCOORD y2, MWPIXELVAL c);
static void SVGA_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w,
MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op);
SCREENDEVICE scrdev = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
SVGA_open,
SVGA_close,
SVGA_getscreeninfo,
SVGA_setpalette,
SVGA_drawpixel,
SVGA_readpixel,
SVGA_drawhline,
SVGA_drawvline,
SVGA_fillrect,
gen_fonts,
SVGA_blit,
NULL, /* PreSelect*/
NULL, /* DrawArea subdriver*/
NULL, /* SetIOPermissions*/
gen_allocatememgc,
NULL, /* MapMemGC*/
NULL, /* FreeMemGC*/
NULL, /* StretchBlit subdriver*/
NULL /* SetPortrait*/
};
extern int gr_mode; /* temp kluge*/
static PSD
SVGA_open(PSD psd)
{
int mode;
vga_modeinfo * modeinfo;
vga_init();
mode = G800x600x256;
if(!vga_hasmode(mode))
mode = G640x480x256;
if(!vga_hasmode(mode))
mode = G640x480x16;
if(vga_setmode(mode) == -1)
return NULL;
modeinfo = vga_getmodeinfo(mode);
psd->xres = psd->xvirtres = modeinfo->width;
psd->yres = psd->yvirtres = modeinfo->height;
psd->linelen = modeinfo->linewidth;
psd->ncolors = modeinfo->colors;
if(psd->ncolors == 256) {
psd->planes = 1;
psd->bpp = 8;
} else {
psd->planes = 4;
psd->bpp = 4;
}
/* note: must change psd->pixtype here for truecolor systems*/
psd->pixtype = MWPF_PALETTE;
psd->flags = PSF_SCREEN;
psd->size = 0;
psd->addr = NULL;
/*DPRINTF("mode: %dx%dx%d bpp %d\n", psd->xres, psd->yres,
psd->ncolors, psd->bpp);*/
return psd;
}
static void
SVGA_close(PSD psd)
{
vga_setmode(TEXT);
}
static void
SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
{
psi->rows = psd->yvirtres;
psi->cols = psd->xvirtres;
psi->planes = psd->planes;
psi->bpp = psd->bpp;
psi->ncolors = psd->ncolors;
psi->fonts = NUMBER_FONTS;
psi->portrait = MWPF_PORTRAIT_NONE;
psi->fbdriver = FALSE; /* not running fb driver, no direct map*/
psi->pixtype = psd->pixtype;
psi->rmask = 0xff;
psi->gmask = 0xff;
psi->bmask = 0xff;
if(psd->yvirtres > 480) {
/* SVGA 800x600*/
psi->xdpcm = 33; /* assumes screen width of 24 cm*/
psi->ydpcm = 33; /* assumes screen height of 18 cm*/
} else if(psd->yvirtres > 350) {
/* VGA 640x480*/
psi->xdpcm = 27; /* assumes screen width of 24 cm*/
psi->ydpcm = 27; /* assumes screen height of 18 cm*/
} else {
/* EGA 640x350*/
psi->xdpcm = 27; /* assumes screen width of 24 cm*/
psi->ydpcm = 19; /* assumes screen height of 18 cm*/
}
}
static void
SVGA_setpalette(PSD psd,int first,int count,MWPALENTRY *pal)
{
while(first < 256 && count-- > 0) {
vga_setpalette(first++, pal->r>>2, pal->g>>2, pal->b>>2);
++pal;
}
}
static void
SVGA_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c)
{
unsigned char gline, line = c;
if(gr_mode == MWMODE_COPY) {
/* vga_drawpixel apparently doesn't work with 256 colors...
* vga_setegacolor(c);
* vga_drawpixel(x, y);
*/
vga_drawscansegment(&line, x, y, 1);
return;
}
/*
* This fishery is required because vgalib doesn't support
* xor drawing mode without acceleration.
*/
vga_getscansegment(&gline, x, y, 1);
line ^= gline;
vga_drawscansegment(&line, x, y, 1);
}
static MWPIXELVAL
SVGA_readpixel(PSD psd,MWCOORD x, MWCOORD y)
{
return vga_getpixel(x, y);
}
static void
SVGA_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
{
int i, width;
unsigned char getline[MAXLINELEN];
static int lastcolor = -1;
static int lastwidth = -1;
static unsigned char line[MAXLINELEN];
/*
* All this fishery is required for two reasons:
* one, vga_drawline is way too slow to be called to fill
* rectangles, so vga_drawscansegment is used instead. In
* addition, vgalib doesn't support xor drawing mode
* without acceleration!!, so we've got to do it ourselves
* with vga_getscansegment...
*/
width = x2-x1+1;
/* this is faster than calling vga_drawline !!!*/
if(width != lastwidth || c != lastcolor) {
lastwidth = width;
lastcolor = c;
for(i=0; i<width; ++i)
line[i] = c;
}
if(gr_mode == MWMODE_XOR) {
vga_getscansegment(getline, x1, y, width);
for(i=0; i<width; ++i)
line[i] ^= getline[i];
lastwidth = -1;
}
vga_drawscansegment(line, x1, y, width);
/*
* Non-fishery version is *slow* and doesn't support XOR.
vga_setegacolor(c);
vga_drawline(x1, y, x2, y2);
*/
}
static void
SVGA_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
{
if(gr_mode == MWMODE_COPY) {
vga_setegacolor(c);
vga_drawline(x, y1, x, y2);
}
/* slower version required for XOR drawing support*/
while(y1 <= y2)
SVGA_drawpixel(psd, x, y1++, c);
}
static void
SVGA_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
{
while(y1 <= y2)
SVGA_drawhline(psd, x1, x2, y1++, c);
}
/* only screen-to-screen blit implemented, op ignored*/
/* FIXME*/
static void
SVGA_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
{
unsigned char line[MAXLINELEN];
assert (dstx >= 0 && dstx < dstpsd->xres);
assert (dsty >= 0 && dsty < dstpsd->yres);
assert (w > 0);
assert (h > 0);
assert (srcx >= 0 && srcx < srcpsd->xres);
assert (srcy >= 0 && srcy < srcpsd->yres);
assert (dstx+w <= dstpsd->xres);
assert (dsty+h <= dstpsd->yres);
assert (srcx+w <= srcpsd->xres);
assert (srcy+h <= srcpsd->yres);
if(!(srcpsd->flags & PSF_SCREEN) || !(dstpsd->flags & PSF_SCREEN))
return;
while(--h >= 0) {
vga_getscansegment(line, srcx, srcy, w);
vga_drawscansegment(line, dstx, dsty, w);
++dsty;
++srcy;
}
}
static int fade = 100;
/* experimental palette animation*/
void
setfadelevel(PSD psd, int f)
{
int i;
extern MWPALENTRY gr_palette[256];
MWPALENTRY local_palette[256];
if(psd->pixtype != MWPF_PALETTE)
return;
fade = f;
if(fade > 100)
fade = 100;
for(i=0; i<256; ++i) {
local_palette[i].r = (gr_palette[i].r * fade / 100);
local_palette[i].g = (gr_palette[i].g * fade / 100);
local_palette[i].b = (gr_palette[i].b * fade / 100);
}
SVGA_setpalette( psd, 0,256,local_palette );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -