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