]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/scr_svga.c
Cleanup CVS ipmorted branch
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / scr_svga.c
1 /*
2  * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
3  *
4  * Microwindows Screen Driver using SVGA Library
5  *
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
11  *
12  * All graphics drawing primitives are based on top of these functions.
13  */
14 /*#define NDEBUG*/
15 #include <assert.h>
16 #include <stdio.h>
17 #include <vga.h>
18 #include "device.h"
19 #include "genfont.h"
20 #include "genmem.h"
21
22 #define MAXLINELEN      800     /* max line byte/pixel length*/
23
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);
37
38 SCREENDEVICE    scrdev = {
39         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
40         SVGA_open,
41         SVGA_close,
42         SVGA_getscreeninfo,
43         SVGA_setpalette,
44         SVGA_drawpixel,
45         SVGA_readpixel,
46         SVGA_drawhline,
47         SVGA_drawvline,
48         SVGA_fillrect,
49         gen_fonts,
50         SVGA_blit,
51         NULL,                   /* PreSelect*/
52         NULL,                   /* DrawArea subdriver*/
53         NULL,                   /* SetIOPermissions*/
54         gen_allocatememgc,
55         NULL,                   /* MapMemGC*/
56         NULL,                   /* FreeMemGC*/
57         NULL,                   /* StretchBlit subdriver*/
58         NULL                    /* SetPortrait*/
59 };
60
61 extern int gr_mode;     /* temp kluge*/
62
63 static PSD
64 SVGA_open(PSD psd)
65 {
66         int             mode;
67         vga_modeinfo *  modeinfo;
68
69         vga_init();
70
71         mode = G800x600x256;
72         if(!vga_hasmode(mode))
73                 mode = G640x480x256;
74         if(!vga_hasmode(mode))
75                 mode = G640x480x16;
76         if(vga_setmode(mode) == -1)
77                 return NULL;
78         modeinfo = vga_getmodeinfo(mode);
79
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) {
85                 psd->planes = 1;
86                 psd->bpp = 8;
87         } else {
88                 psd->planes = 4;
89                 psd->bpp = 4;
90         }
91         /* note: must change psd->pixtype here for truecolor systems*/
92         psd->pixtype = MWPF_PALETTE;
93         psd->flags = PSF_SCREEN;
94         psd->size = 0;
95         psd->addr = NULL;
96
97         /*DPRINTF("mode: %dx%dx%d bpp %d\n", psd->xres, psd->yres,
98                 psd->ncolors, psd->bpp);*/
99
100         return psd;
101 }
102
103 static void
104 SVGA_close(PSD psd)
105 {
106         vga_setmode(TEXT);
107 }
108
109 static void
110 SVGA_getscreeninfo(PSD psd,PMWSCREENINFO psi)
111 {
112         psi->rows = psd->yvirtres;
113         psi->cols = psd->xvirtres;
114         psi->planes = psd->planes;
115         psi->bpp = psd->bpp;
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;
121         psi->rmask      = 0xff;
122         psi->gmask      = 0xff;
123         psi->bmask      = 0xff;
124
125         if(psd->yvirtres > 480) {
126                 /* SVGA 800x600*/
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) {
130                 /* VGA 640x480*/
131                 psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
132                 psi->ydpcm = 27;        /* assumes screen height of 18 cm*/
133         } else {
134                 /* EGA 640x350*/
135                 psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
136                 psi->ydpcm = 19;        /* assumes screen height of 18 cm*/
137         }
138 }
139
140 static void
141 SVGA_setpalette(PSD psd,int first,int count,MWPALENTRY *pal)
142 {
143         while(first < 256 && count-- > 0) {
144                 vga_setpalette(first++, pal->r>>2, pal->g>>2, pal->b>>2);
145                 ++pal;
146         }
147 }
148
149 static void
150 SVGA_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c)
151 {
152         unsigned char gline, line = c;
153
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);
158                  */
159                 vga_drawscansegment(&line, x, y, 1);
160                 return;
161         }
162         /*
163          * This fishery is required because vgalib doesn't support
164          * xor drawing mode without acceleration.
165          */
166         vga_getscansegment(&gline, x, y, 1);
167         line ^= gline;
168         vga_drawscansegment(&line, x, y, 1);
169 }
170
171 static MWPIXELVAL
172 SVGA_readpixel(PSD psd,MWCOORD x, MWCOORD y)
173 {
174         return vga_getpixel(x, y);
175 }
176
177 static void
178 SVGA_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
179 {
180         int     i, width;
181         unsigned char getline[MAXLINELEN];
182         static int lastcolor = -1;
183         static int lastwidth = -1;
184         static unsigned char line[MAXLINELEN];
185
186         /*
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...
193          */
194         width = x2-x1+1;
195
196         /* this is faster than calling vga_drawline !!!*/
197         if(width != lastwidth || c != lastcolor) {
198                 lastwidth = width;
199                 lastcolor = c;
200                 for(i=0; i<width; ++i)
201                         line[i] = c;
202         }
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];
207                 lastwidth = -1;
208         }
209         vga_drawscansegment(line, x1, y, width);
210
211         /*
212          * Non-fishery version is *slow* and doesn't support XOR.
213         vga_setegacolor(c);
214         vga_drawline(x1, y, x2, y2);
215          */
216 }
217
218 static void
219 SVGA_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
220 {
221         if(gr_mode == MWMODE_COPY) {
222                 vga_setegacolor(c);
223                 vga_drawline(x, y1, x, y2);
224         }
225
226         /* slower version required for XOR drawing support*/
227         while(y1 <= y2)
228                 SVGA_drawpixel(psd, x, y1++, c);
229 }
230
231 static void
232 SVGA_fillrect(PSD psd,MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
233 {
234         while(y1 <= y2)
235                 SVGA_drawhline(psd, x1, x2, y1++, c);
236 }
237
238 /* only screen-to-screen blit implemented, op ignored*/
239 /* FIXME*/
240 static void
241 SVGA_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
242         PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
243 {
244         unsigned char line[MAXLINELEN];
245
246         assert (dstx >= 0 && dstx < dstpsd->xres);
247         assert (dsty >= 0 && dsty < dstpsd->yres);
248         assert (w > 0);
249         assert (h > 0);
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);
256
257         if(!(srcpsd->flags & PSF_SCREEN) || !(dstpsd->flags & PSF_SCREEN))
258                 return;
259
260         while(--h >= 0) {
261                 vga_getscansegment(line, srcx, srcy, w);
262                 vga_drawscansegment(line, dstx, dsty, w);
263                 ++dsty;
264                 ++srcy;
265         }
266 }
267
268 static int fade = 100;
269 /* experimental palette animation*/
270 void
271 setfadelevel(PSD psd, int f)
272 {
273         int             i;
274         extern MWPALENTRY gr_palette[256];
275         MWPALENTRY local_palette[256];
276
277         if(psd->pixtype != MWPF_PALETTE)
278                 return;
279
280         fade = f;
281         if(fade > 100)
282                 fade = 100;
283         for(i=0; i<256; ++i) {
284
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);
288         }
289    SVGA_setpalette( psd, 0,256,local_palette );
290 }