]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/fblin32.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / fblin32.c
1 /*
2  * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
3  *
4  * 32bpp Linear Video Driver for Microwindows
5  *
6  * Inspired from Ben Pfaff's BOGL <pfaffben@debian.org>
7  */
8 /*#define NDEBUG*/
9 #include <assert.h>
10 #include <string.h>
11 #include "device.h"
12 #include "fb.h"
13
14 /* Calc linelen and mmap size, return 0 on fail*/
15 static int
16 linear32_init(PSD psd)
17 {
18         if (!psd->size) {
19                 psd->size = psd->yres * psd->linelen;
20                 /* convert linelen from byte to pixel len for bpp 16, 24, 32*/
21                 psd->linelen /= 4;
22         }
23         return 1;
24 }
25
26 /* Set pixel at x, y, to pixelval c*/
27 static void
28 linear32_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
29 {
30         ADDR32  addr = psd->addr;
31
32         assert (addr != 0);
33         assert (x >= 0 && x < psd->xres);
34         assert (y >= 0 && y < psd->yres);
35         assert (c < psd->ncolors);
36
37         DRAWON;
38         if (gr_mode == MWMODE_COPY)
39                 addr[x + y * psd->linelen] = c;
40         else
41                 applyOp(gr_mode, c, &addr[x + y * psd->linelen], ADDR32);
42         DRAWOFF;
43 }
44
45 /* Read pixel at x, y*/
46 static MWPIXELVAL
47 linear32_readpixel(PSD psd, MWCOORD x, MWCOORD y)
48 {
49         ADDR32  addr = psd->addr;
50
51         assert (addr != 0);
52         assert (x >= 0 && x < psd->xres);
53         assert (y >= 0 && y < psd->yres);
54
55         return addr[x + y * psd->linelen];
56 }
57
58 /* Draw horizontal line from x1,y to x2,y including final point*/
59 static void
60 linear32_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
61 {
62         ADDR32  addr = psd->addr;
63
64         assert (addr != 0);
65         assert (x1 >= 0 && x1 < psd->xres);
66         assert (x2 >= 0 && x2 < psd->xres);
67         assert (x2 >= x1);
68         assert (y >= 0 && y < psd->yres);
69         assert (c < psd->ncolors);
70
71         DRAWON;
72         addr += x1 + y * psd->linelen;
73         if(gr_mode == MWMODE_COPY) {
74                 /* FIXME: memsetl(dst, c, x2-x1+1)*/
75                 while(x1++ <= x2)
76                         *addr++ = c;
77         } else {
78                 while(x1++ <= x2) {
79                         applyOp(gr_mode, c, addr, ADDR32);
80                         ++addr;
81                 }
82         }
83         DRAWOFF;
84 }
85
86 /* Draw a vertical line from x,y1 to x,y2 including final point*/
87 static void
88 linear32_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
89 {
90         ADDR32  addr = psd->addr;
91         int     linelen = psd->linelen;
92
93         assert (addr != 0);
94         assert (x >= 0 && x < psd->xres);
95         assert (y1 >= 0 && y1 < psd->yres);
96         assert (y2 >= 0 && y2 < psd->yres);
97         assert (y2 >= y1);
98         assert (c < psd->ncolors);
99
100         DRAWON;
101         addr += x + y1 * linelen;
102         if(gr_mode == MWMODE_COPY) {
103                 while(y1++ <= y2) {
104                         *addr = c;
105                         addr += linelen;
106                 }
107         } else {
108                 while(y1++ <= y2) {
109                         applyOp(gr_mode, c, addr, ADDR32);
110                         addr += linelen;
111                 }
112         }
113         DRAWOFF;
114 }
115
116 /* srccopy bitblt*/
117 static void
118 linear32_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
119         PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
120 {
121         ADDR8   dst8, src8;
122         ADDR32  dst = dstpsd->addr;
123         ADDR32  src = srcpsd->addr;
124         int     i;
125         int     dlinelen = dstpsd->linelen;
126         int     slinelen = srcpsd->linelen;
127         int     dlinelen_minus_w4;
128         int     slinelen_minus_w4;
129 #if ALPHABLEND
130         unsigned int alpha;
131 #endif
132
133         assert (dst != 0);
134         assert (dstx >= 0 && dstx < dstpsd->xres);
135         assert (dsty >= 0 && dsty < dstpsd->yres);
136         assert (w > 0);
137         assert (h > 0);
138         assert (src != 0);
139         assert (srcx >= 0 && srcx < srcpsd->xres);
140         assert (srcy >= 0 && srcy < srcpsd->yres);
141         assert (dstx+w <= dstpsd->xres);
142         assert (dsty+h <= dstpsd->yres);
143         assert (srcx+w <= srcpsd->xres);
144         assert (srcy+h <= srcpsd->yres);
145
146         DRAWON;
147         dst += dstx + dsty * dlinelen;
148         src += srcx + srcy * slinelen;
149
150 #if ALPHABLEND
151         if((op & MWROP_EXTENSION) != MWROP_BLENDCONSTANT)
152                 goto stdblit;
153         alpha = op & 0xff;
154
155         src8 = (ADDR8)src;
156         dst8 = (ADDR8)dst;
157         dlinelen_minus_w4 = (dlinelen - w) * 4;
158         slinelen_minus_w4 = (slinelen - w) * 4;
159         while(--h >= 0) {
160                 for(i=0; i<w; ++i) {
161                         register unsigned long s = *src8++;
162                         register unsigned long d = *dst8;
163                         *dst8++ = (unsigned char)(((s - d)*alpha)>>8) + d;
164                         s = *src8++;
165                         d = *dst8;
166                         *dst8++ = (unsigned char)(((s - d)*alpha)>>8) + d;
167                         s = *src8;
168                         d = *dst8;
169                         *dst8 = (unsigned char)(((s - d)*alpha)>>8) + d;
170                         dst8 += 2;
171                         src8 += 2;
172                 }
173                 dst8 += dlinelen_minus_w4;
174                 src8 += slinelen_minus_w4;
175         }
176         DRAWOFF;
177         return;
178 stdblit:
179 #endif
180
181         if (op == MWROP_COPY) {
182                 /* copy from bottom up if dst in src rectangle*/
183                 /* memmove is used to handle x case*/
184                 if (srcy < dsty) {
185                         src += (h-1) * slinelen;
186                         dst += (h-1) * dlinelen;
187                         slinelen *= -1;
188                         dlinelen *= -1;
189                 }
190                 while(--h >= 0) {
191                         /* a _fast_ memmove is a _must_ in this routine*/
192                         memmove(dst, src, w<<2);
193                         dst += dlinelen;
194                         src += slinelen;
195                 }
196         } else {
197                 for(i=0; i < w; ++i) {
198                         applyOp(MWROP_TO_MODE(op), *src, dst, ADDR32);
199                         ++src;
200                         ++dst;
201                 }
202                 dst += dlinelen - w;
203                 src += slinelen - w;
204         }
205         DRAWOFF;
206 }
207
208 /* srccopy stretchblt*/
209 static void
210 linear32_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw,
211         MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw,
212         MWCOORD srch, long op)
213 {
214         ADDR32  dst;
215         ADDR32  src;
216         int     dlinelen = dstpsd->linelen;
217         int     slinelen = srcpsd->linelen;
218         int     i, ymax;
219         int     row_pos, row_inc;
220         int     col_pos, col_inc;
221         unsigned long pixel = 0;
222
223         assert (dstpsd->addr != 0);
224         assert (dstx >= 0 && dstx < dstpsd->xres);
225         assert (dsty >= 0 && dsty < dstpsd->yres);
226         assert (dstw > 0);
227         assert (dsth > 0);
228         assert (srcpsd->addr != 0);
229         assert (srcx >= 0 && srcx < srcpsd->xres);
230         assert (srcy >= 0 && srcy < srcpsd->yres);
231         assert (srcw > 0);
232         assert (srch > 0);
233         assert (dstx+dstw <= dstpsd->xres);
234         assert (dsty+dsth <= dstpsd->yres);
235         assert (srcx+srcw <= srcpsd->xres);
236         assert (srcy+srch <= srcpsd->yres);
237
238         DRAWON;
239         row_pos = 0x10000;
240         row_inc = (srch << 16) / dsth;
241
242         /* stretch blit using integer ratio between src/dst height/width*/
243         for (ymax = dsty+dsth; dsty<ymax; ++dsty) {
244
245                 /* find source y position*/
246                 while (row_pos >= 0x10000L) {
247                         ++srcy;
248                         row_pos -= 0x10000L;
249                 }
250
251                 dst = (ADDR32)dstpsd->addr + dstx + dsty*dlinelen;
252                 src = (ADDR32)srcpsd->addr + srcx + (srcy-1)*slinelen;
253
254                 /* copy a row of pixels*/
255                 col_pos = 0x10000;
256                 col_inc = (srcw << 16) / dstw;
257                 for (i=0; i<dstw; ++i) {
258                         /* get source x pixel*/
259                         while (col_pos >= 0x10000L) {
260                                 pixel = *src++;
261                                 col_pos -= 0x10000L;
262                         }
263                         *dst++ = pixel;
264                         col_pos += col_inc;
265                 }
266
267                 row_pos += row_inc;
268         }
269         DRAWOFF;
270 }
271
272 SUBDRIVER fblinear32 = {
273         linear32_init,
274         linear32_drawpixel,
275         linear32_readpixel,
276         linear32_drawhorzline,
277         linear32_drawvertline,
278         gen_fillrect,
279         linear32_blit,
280         NULL,
281         linear32_stretchblit
282 };