]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/fblin4rev.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / fblin4rev.c
1 /*
2  * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com>
3  *
4  * 4bpp Packed Linear Video Driver (reversed nibble order)
5  * For Psion S5
6  *
7  * If INVERT4BPP is defined, then the values are inverted before drawing.
8  *
9  *      In this driver, psd->linelen is line byte length, not line pixel length
10  */
11 /*#define NDEBUG*/
12 #include <assert.h>
13 #include <string.h>
14 #include "device.h"
15 #include "fb.h"
16
17 #if INVERT4BPP
18 #define INVERT(c)       ((c) = (~c & 0x0f))
19 #else
20 #define INVERT(c)
21 #endif
22
23 static unsigned char notmask[2] = { 0xf0, 0x0f};
24
25 /* Calc linelen and mmap size, return 0 on fail*/
26 static int
27 linear4_init(PSD psd)
28 {
29         if (!psd->size)
30                 psd->size = psd->yres * psd->linelen;
31         /* linelen in bytes for bpp 1, 2, 4, 8 so no change*/
32         return 1;
33 }
34
35 /* Set pixel at x, y, to pixelval c*/
36 static void
37 linear4_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
38 {
39         ADDR8   addr = psd->addr;
40
41         assert (addr != 0);
42         assert (x >= 0 && x < psd->xres);
43         assert (y >= 0 && y < psd->yres);
44         assert (c < psd->ncolors);
45
46         INVERT(c);
47         DRAWON;
48         addr += (x>>1) + y * psd->linelen;
49         if(gr_mode == MWMODE_XOR)
50                 *addr ^= c << ((x&1)<<2);
51         else
52                 *addr = (*addr & notmask[x&1]) | (c << ((x&1)<<2));
53         DRAWOFF;
54 }
55
56 /* Read pixel at x, y*/
57 static MWPIXELVAL
58 linear4_readpixel(PSD psd, MWCOORD x, MWCOORD y)
59 {
60         ADDR8           addr = psd->addr;
61         MWPIXELVAL      c;
62
63         assert (addr != 0);
64         assert (x >= 0 && x < psd->xres);
65         assert (y >= 0 && y < psd->yres);
66
67         c = (addr[(x>>1) + y * psd->linelen] >> ((x&1)<<2) ) & 0x0f;
68         INVERT(c);
69         return c;
70         
71 }
72
73 /* Draw horizontal line from x1,y to x2,y including final point*/
74 static void
75 linear4_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
76 {
77         ADDR8   addr = psd->addr;
78
79         assert (addr != 0);
80         assert (x1 >= 0 && x1 < psd->xres);
81         assert (x2 >= 0 && x2 < psd->xres);
82         assert (x2 >= x1);
83         assert (y >= 0 && y < psd->yres);
84         assert (c < psd->ncolors);
85
86         INVERT(c);
87         DRAWON;
88         addr += (x1>>1) + y * psd->linelen;
89         if(gr_mode == MWMODE_XOR) {
90                 while(x1 <= x2) {
91                         *addr ^= c << ((x1&1)<<2);
92                         if((++x1 & 1) == 0)
93                                 ++addr;
94                 }
95         } else {
96                 while(x1 <= x2) {
97                         *addr = (*addr & notmask[x1&1]) | (c << ((x1&1)<<2));
98                         if((++x1 & 1) == 0)
99                                 ++addr;
100                 }
101         }
102         DRAWOFF;
103 }
104
105 /* Draw a vertical line from x,y1 to x,y2 including final point*/
106 static void
107 linear4_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
108 {
109         ADDR8   addr = psd->addr;
110         int     linelen = psd->linelen;
111
112         assert (addr != 0);
113         assert (x >= 0 && x < psd->xres);
114         assert (y1 >= 0 && y1 < psd->yres);
115         assert (y2 >= 0 && y2 < psd->yres);
116         assert (y2 >= y1);
117         assert (c < psd->ncolors);
118
119         INVERT(c);
120         DRAWON;
121         addr += (x>>1) + y1 * linelen;
122         if(gr_mode == MWMODE_XOR)
123                 while(y1++ <= y2) {
124                         *addr ^= c << ((x&1)<<2);
125                         addr += linelen;
126                 }
127         else
128                 while(y1++ <= y2) {
129                         *addr = (*addr & notmask[x&1]) | (c << ((x&1)<<2));
130                         addr += linelen;
131                 }
132         DRAWOFF;
133 }
134
135 /* srccopy bitblt, opcode is currently ignored*/
136 static void
137 linear4_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
138         PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
139 {
140         ADDR8   dst;
141         ADDR8   src;
142         int     i;
143         int     dlinelen = dstpsd->linelen;
144         int     slinelen = srcpsd->linelen;
145
146         assert (dstpsd->addr != 0);
147         assert (dstx >= 0 && dstx < dstpsd->xres);
148         assert (dsty >= 0 && dsty < dstpsd->yres);
149         assert (w > 0);
150         assert (h > 0);
151         assert (srcpsd->addr != 0);
152         assert (srcx >= 0 && srcx < srcpsd->xres);
153         assert (srcy >= 0 && srcy < srcpsd->yres);
154         assert (dstx+w <= dstpsd->xres);
155         assert (dsty+h <= dstpsd->yres);
156         assert (srcx+w <= srcpsd->xres);
157         assert (srcy+h <= srcpsd->yres);
158
159         DRAWON;
160         dst = dstpsd->addr + (dstx>>1) + dsty * dlinelen;
161         src = srcpsd->addr + (srcx>>1) + srcy * slinelen;
162         while(--h >= 0) {
163                 ADDR8   d = dst;
164                 ADDR8   s = src;
165                 MWCOORD dx = dstx;
166                 MWCOORD sx = srcx;
167                 for(i=0; i<w; ++i) {
168 #if INVERT4BPP
169                         unsigned char c = *s;
170                         INVERT(c);
171                         *d = (*d & notmask[dx&1]) |
172                            ((c >> ((sx&1)<<2) & 0x0f) << ((dx&1)<<2));
173 #else
174                         *d = (*d & notmask[dx&1]) |
175                            ((*s >> ((sx&1)<<2) & 0x0f) << ((dx&1)<<2));
176 #endif
177                         if((++dx & 1) == 0)
178                                 ++d;
179                         if((++sx & 1) == 0)
180                                 ++s;
181                 }
182                 dst += dlinelen;
183                 src += slinelen;
184         }
185         DRAWOFF;
186 }
187
188 SUBDRIVER fblinear4 = {
189         linear4_init,
190         linear4_drawpixel,
191         linear4_readpixel,
192         linear4_drawhorzline,
193         linear4_drawvertline,
194         gen_fillrect,
195         linear4_blit
196 };