2 * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
4 * Microwindows Screen Driver using SVGA Library
6 * This driver requires the following SVGA entry points:
7 * vga_init, vga_setmode,
8 * vga_drawpixel, vga_getpixel,
9 * vga_setegacolor, vga_drawline,
10 * vga_getscansegment, vga_drawscansegment
12 * All graphics drawing primitives are based on top of these functions.
22 #define MAXLINELEN 800 /* max line byte/pixel length*/
24 /* specific driver entry points*/
25 static PSD SVGA_open(PSD psd);
26 static void SVGA_close(PSD psd);
27 static void SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi);
28 static void SVGA_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);
29 static void SVGA_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);
30 static MWPIXELVAL SVGA_readpixel(PSD psd,MWCOORD x, MWCOORD y);
31 static void SVGA_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);
32 static void SVGA_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c);
33 static void SVGA_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2,
34 MWCOORD y2, MWPIXELVAL c);
35 static void SVGA_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w,
36 MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op);
38 SCREENDEVICE scrdev = {
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
52 NULL, /* DrawArea subdriver*/
53 NULL, /* SetIOPermissions*/
57 NULL, /* StretchBlit subdriver*/
61 extern int gr_mode; /* temp kluge*/
67 vga_modeinfo * modeinfo;
72 if(!vga_hasmode(mode))
74 if(!vga_hasmode(mode))
76 if(vga_setmode(mode) == -1)
78 modeinfo = vga_getmodeinfo(mode);
80 psd->xres = psd->xvirtres = modeinfo->width;
81 psd->yres = psd->yvirtres = modeinfo->height;
82 psd->linelen = modeinfo->linewidth;
83 psd->ncolors = modeinfo->colors;
84 if(psd->ncolors == 256) {
91 /* note: must change psd->pixtype here for truecolor systems*/
92 psd->pixtype = MWPF_PALETTE;
93 psd->flags = PSF_SCREEN;
97 /*DPRINTF("mode: %dx%dx%d bpp %d\n", psd->xres, psd->yres,
98 psd->ncolors, psd->bpp);*/
110 SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
112 psi->rows = psd->yvirtres;
113 psi->cols = psd->xvirtres;
114 psi->planes = psd->planes;
116 psi->ncolors = psd->ncolors;
117 psi->fonts = NUMBER_FONTS;
118 psi->portrait = MWPF_PORTRAIT_NONE;
119 psi->fbdriver = FALSE; /* not running fb driver, no direct map*/
120 psi->pixtype = psd->pixtype;
125 if(psd->yvirtres > 480) {
127 psi->xdpcm = 33; /* assumes screen width of 24 cm*/
128 psi->ydpcm = 33; /* assumes screen height of 18 cm*/
129 } else if(psd->yvirtres > 350) {
131 psi->xdpcm = 27; /* assumes screen width of 24 cm*/
132 psi->ydpcm = 27; /* assumes screen height of 18 cm*/
135 psi->xdpcm = 27; /* assumes screen width of 24 cm*/
136 psi->ydpcm = 19; /* assumes screen height of 18 cm*/
141 SVGA_setpalette(PSD psd,int first,int count,MWPALENTRY *pal)
143 while(first < 256 && count-- > 0) {
144 vga_setpalette(first++, pal->r>>2, pal->g>>2, pal->b>>2);
150 SVGA_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c)
152 unsigned char gline, line = c;
154 if(gr_mode == MWMODE_COPY) {
155 /* vga_drawpixel apparently doesn't work with 256 colors...
156 * vga_setegacolor(c);
157 * vga_drawpixel(x, y);
159 vga_drawscansegment(&line, x, y, 1);
163 * This fishery is required because vgalib doesn't support
164 * xor drawing mode without acceleration.
166 vga_getscansegment(&gline, x, y, 1);
168 vga_drawscansegment(&line, x, y, 1);
172 SVGA_readpixel(PSD psd,MWCOORD x, MWCOORD y)
174 return vga_getpixel(x, y);
178 SVGA_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
181 unsigned char getline[MAXLINELEN];
182 static int lastcolor = -1;
183 static int lastwidth = -1;
184 static unsigned char line[MAXLINELEN];
187 * All this fishery is required for two reasons:
188 * one, vga_drawline is way too slow to be called to fill
189 * rectangles, so vga_drawscansegment is used instead. In
190 * addition, vgalib doesn't support xor drawing mode
191 * without acceleration!!, so we've got to do it ourselves
192 * with vga_getscansegment...
196 /* this is faster than calling vga_drawline !!!*/
197 if(width != lastwidth || c != lastcolor) {
200 for(i=0; i<width; ++i)
203 if(gr_mode == MWMODE_XOR) {
204 vga_getscansegment(getline, x1, y, width);
205 for(i=0; i<width; ++i)
206 line[i] ^= getline[i];
209 vga_drawscansegment(line, x1, y, width);
212 * Non-fishery version is *slow* and doesn't support XOR.
214 vga_drawline(x1, y, x2, y2);
219 SVGA_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
221 if(gr_mode == MWMODE_COPY) {
223 vga_drawline(x, y1, x, y2);
226 /* slower version required for XOR drawing support*/
228 SVGA_drawpixel(psd, x, y1++, c);
232 SVGA_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
235 SVGA_drawhline(psd, x1, x2, y1++, c);
238 /* only screen-to-screen blit implemented, op ignored*/
241 SVGA_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
242 PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
244 unsigned char line[MAXLINELEN];
246 assert (dstx >= 0 && dstx < dstpsd->xres);
247 assert (dsty >= 0 && dsty < dstpsd->yres);
250 assert (srcx >= 0 && srcx < srcpsd->xres);
251 assert (srcy >= 0 && srcy < srcpsd->yres);
252 assert (dstx+w <= dstpsd->xres);
253 assert (dsty+h <= dstpsd->yres);
254 assert (srcx+w <= srcpsd->xres);
255 assert (srcy+h <= srcpsd->yres);
257 if(!(srcpsd->flags & PSF_SCREEN) || !(dstpsd->flags & PSF_SCREEN))
261 vga_getscansegment(line, srcx, srcy, w);
262 vga_drawscansegment(line, dstx, dsty, w);
268 static int fade = 100;
269 /* experimental palette animation*/
271 setfadelevel(PSD psd, int f)
274 extern MWPALENTRY gr_palette[256];
275 MWPALENTRY local_palette[256];
277 if(psd->pixtype != MWPF_PALETTE)
283 for(i=0; i<256; ++i) {
285 local_palette[i].r = (gr_palette[i].r * fade / 100);
286 local_palette[i].g = (gr_palette[i].g * fade / 100);
287 local_palette[i].b = (gr_palette[i].b * fade / 100);
289 SVGA_setpalette( psd, 0,256,local_palette );