OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [fblin8.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
3
 *
4
 * 8bpp Linear Video Driver for Microwindows
5
 *      00/01/26 added alpha blending with lookup tables (64k total)
6
 *
7
 * Inspired from Ben Pfaff's BOGL <pfaffben@debian.org>
8
 */
9
/*#define NDEBUG*/
10
#include <assert.h>
11
 
12
/* We want to do string copying fast, so inline assembly if possible */
13
#ifndef __OPTIMIZE__
14
#define __OPTIMIZE__
15
#endif
16
#include <string.h>
17
 
18
#include "device.h"
19
#include "fb.h"
20
 
21
#if ALPHABLEND
22
/*
23
 * Alpha lookup tables for 256 color palette systems
24
 * A 5 bit alpha value is used to keep tables smaller.
25
 *
26
 * Two tables are created.  The first, alpha_to_rgb contains 15 bit RGB
27
 * values for each alpha value for each color: 32*256 short words.
28
 * RGB values can then be blended.  The second, rgb_to_palindex contains
29
 * the closest color (palette index) for each of the 5-bit
30
 * R, G, and B values: 32*32*32 bytes.
31
 */
32
static unsigned short *alpha_to_rgb = NULL;
33
static unsigned char  *rgb_to_palindex = NULL;
34
void init_alpha_lookup(void);
35
#endif
36
 
37
/* Calc linelen and mmap size, return 0 on fail*/
38
static int
39
linear8_init(PSD psd)
40
{
41
        if (!psd->size)
42
                psd->size = psd->yres * psd->linelen;
43
        /* linelen in bytes for bpp 1, 2, 4, 8 so no change*/
44
        return 1;
45
}
46
 
47
/* Set pixel at x, y, to pixelval c*/
48
static void
49
linear8_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
50
{
51
        ADDR8   addr = psd->addr;
52
 
53
        assert (addr != 0);
54
        assert (x >= 0 && x < psd->xres);
55
        assert (y >= 0 && y < psd->yres);
56
        assert (c < psd->ncolors);
57
 
58
        DRAWON;
59
        if(gr_mode == MWMODE_COPY)
60
                addr[x + y * psd->linelen] = c;
61
        else
62
                applyOp(gr_mode, c, &addr[ x + y * psd->linelen], ADDR8);
63
        DRAWOFF;
64
}
65
 
66
/* Read pixel at x, y*/
67
static MWPIXELVAL
68
linear8_readpixel(PSD psd, MWCOORD x, MWCOORD y)
69
{
70
        ADDR8   addr = psd->addr;
71
 
72
        assert (addr != 0);
73
        assert (x >= 0 && x < psd->xres);
74
        assert (y >= 0 && y < psd->yres);
75
 
76
        return addr[x + y * psd->linelen];
77
}
78
 
79
/* Draw horizontal line from x1,y to x2,y including final point*/
80
static void
81
linear8_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
82
{
83
        ADDR8   addr = psd->addr;
84
 
85
        assert (addr != 0);
86
        assert (x1 >= 0 && x1 < psd->xres);
87
        assert (x2 >= 0 && x2 < psd->xres);
88
        assert (x2 >= x1);
89
        assert (y >= 0 && y < psd->yres);
90
        assert (c < psd->ncolors);
91
 
92
        DRAWON;
93
        addr += x1 + y * psd->linelen;
94
        if(gr_mode == MWMODE_COPY)
95
                memset(addr, c, x2 - x1 + 1);
96
        else {
97
                while(x1++ <= x2) {
98
                        applyOp(gr_mode, c, addr, ADDR8);
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
linear8_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
        DRAWON;
120
        addr += x + y1 * linelen;
121
        if(gr_mode == MWMODE_COPY) {
122
                while(y1++ <= y2) {
123
                        *addr = c;
124
                        addr += linelen;
125
                }
126
        } else {
127
                while(y1++ <= y2) {
128
                        applyOp(gr_mode, c, addr, ADDR8);
129
                        addr += linelen;
130
                }
131
        }
132
        DRAWOFF;
133
}
134
 
135
/* srccopy bitblt*/
136
static void
137
linear8_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     dlinelen = dstpsd->linelen;
143
        int     slinelen = srcpsd->linelen;
144
#if ALPHABLEND
145
        unsigned int srcalpha, dstalpha;
146
#endif
147
 
148
        assert (dstpsd->addr != 0);
149
        assert (dstx >= 0 && dstx < dstpsd->xres);
150
        assert (dsty >= 0 && dsty < dstpsd->yres);
151
        assert (w > 0);
152
        assert (h > 0);
153
        assert (srcpsd->addr != 0);
154
        assert (srcx >= 0 && srcx < srcpsd->xres);
155
        assert (srcy >= 0 && srcy < srcpsd->yres);
156
        assert (dstx+w <= dstpsd->xres);
157
        assert (dsty+h <= dstpsd->yres);
158
        assert (srcx+w <= srcpsd->xres);
159
        assert (srcy+h <= srcpsd->yres);
160
 
161
        DRAWON;
162
        dst = dstpsd->addr + dstx + dsty * dlinelen;
163
        src = srcpsd->addr + srcx + srcy * slinelen;
164
 
165
#if ALPHABLEND
166
        if((op & MWROP_EXTENSION) != MWROP_BLENDCONSTANT)
167
                goto stdblit;
168
        srcalpha = op & 0xff;
169
 
170
        /* FIXME create lookup table after palette is stabilized...*/
171
        if(!rgb_to_palindex || !alpha_to_rgb) {
172
                init_alpha_lookup();
173
                if(!rgb_to_palindex || !alpha_to_rgb)
174
                        goto stdblit;
175
        }
176
 
177
        /* Create 5 bit alpha value index for 256 color indexing*/
178
 
179
        /* destination alpha is (1 - source) alpha*/
180
        dstalpha = ((srcalpha>>3) ^ 31) << 8;
181
        srcalpha = (srcalpha>>3) << 8;
182
 
183
        while(--h >= 0) {
184
            int i;
185
            for(i=0; i<w; ++i) {
186
                /* Get source RGB555 value for source alpha value*/
187
                unsigned short s = alpha_to_rgb[srcalpha + *src++];
188
 
189
                /* Get destination RGB555 value for dest alpha value*/
190
                unsigned short d = alpha_to_rgb[dstalpha + *dst];
191
 
192
                /* Add RGB values together and get closest palette index to it*/
193
                *dst++ = rgb_to_palindex[s + d];
194
            }
195
            dst += dlinelen - w;
196
            src += slinelen - w;
197
        }
198
        DRAWOFF;
199
        return;
200
stdblit:
201
#endif
202
        if (op == MWROP_COPY) {
203
                /* copy from bottom up if dst in src rectangle*/
204
                /* memmove is used to handle x case*/
205
                if (srcy < dsty) {
206
                        src += (h-1) * slinelen;
207
                        dst += (h-1) * dlinelen;
208
                        slinelen *= -1;
209
                        dlinelen *= -1;
210
                }
211
 
212
                while(--h >= 0) {
213
                        /* a _fast_ memcpy is a _must_ in this routine*/
214
                        memmove(dst, src, w);
215
                        dst += dlinelen;
216
                        src += slinelen;
217
                }
218
        } else {
219
                while (--h >= 0) {
220
                        int i;
221
                        for (i=0; i<w; i++) {
222
                                applyOp(MWROP_TO_MODE(op), *src, dst, ADDR8);
223
                                ++src;
224
                                ++dst;
225
                        }
226
                        dst += dlinelen - w;
227
                        src += slinelen - w;
228
                }
229
        }
230
        DRAWOFF;
231
}
232
 
233
/* srccopy stretchblt*/
234
static void
235
linear8_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw,
236
        MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw,
237
        MWCOORD srch, long op)
238
{
239
        ADDR8   dst;
240
        ADDR8   src;
241
        int     dlinelen = dstpsd->linelen;
242
        int     slinelen = srcpsd->linelen;
243
        int     i, ymax;
244
        int     row_pos, row_inc;
245
        int     col_pos, col_inc;
246
        unsigned char pixel = 0;
247
 
248
        assert (dstpsd->addr != 0);
249
        assert (dstx >= 0 && dstx < dstpsd->xres);
250
        assert (dsty >= 0 && dsty < dstpsd->yres);
251
        assert (dstw > 0);
252
        assert (dsth > 0);
253
        assert (srcpsd->addr != 0);
254
        assert (srcx >= 0 && srcx < srcpsd->xres);
255
        assert (srcy >= 0 && srcy < srcpsd->yres);
256
        assert (srcw > 0);
257
        assert (srch > 0);
258
        assert (dstx+dstw <= dstpsd->xres);
259
        assert (dsty+dsth <= dstpsd->yres);
260
        assert (srcx+srcw <= srcpsd->xres);
261
        assert (srcy+srch <= srcpsd->yres);
262
 
263
        DRAWON;
264
        row_pos = 0x10000;
265
        row_inc = (srch << 16) / dsth;
266
 
267
        /* stretch blit using integer ratio between src/dst height/width*/
268
        for (ymax = dsty+dsth; dsty<ymax; ++dsty) {
269
 
270
                /* find source y position*/
271
                while (row_pos >= 0x10000L) {
272
                        ++srcy;
273
                        row_pos -= 0x10000L;
274
                }
275
 
276
                dst = dstpsd->addr + dstx + dsty*dlinelen;
277
                src = srcpsd->addr + srcx + (srcy-1)*slinelen;
278
 
279
                /* copy a row of pixels*/
280
                col_pos = 0x10000;
281
                col_inc = (srcw << 16) / dstw;
282
                for (i=0; i<dstw; ++i) {
283
                        /* get source x pixel*/
284
                        while (col_pos >= 0x10000L) {
285
                                pixel = *src++;
286
                                col_pos -= 0x10000L;
287
                        }
288
                        *dst++ = pixel;
289
                        col_pos += col_inc;
290
                }
291
 
292
                row_pos += row_inc;
293
        }
294
        DRAWOFF;
295
}
296
 
297
#if ALPHABLEND
298
void
299
init_alpha_lookup(void)
300
{
301
        int     i, a;
302
        int     r, g, b;
303
        extern MWPALENTRY gr_palette[256];
304
 
305
        if(!alpha_to_rgb)
306
                alpha_to_rgb = (unsigned short *)malloc(
307
                        sizeof(unsigned short)*32*256);
308
        if(!rgb_to_palindex)
309
                rgb_to_palindex = (unsigned char *)malloc(
310
                        sizeof(unsigned char)*32*32*32);
311
        if(!rgb_to_palindex || !alpha_to_rgb)
312
                return;
313
 
314
        /*
315
         * Precompute alpha to rgb lookup by premultiplying
316
         * each palette rgb value by each possible alpha
317
         * and storing it as RGB555.
318
         */
319
        for(i=0; i<256; ++i) {
320
                MWPALENTRY *p = &gr_palette[i];
321
                for(a=0; a<32; ++a) {
322
                        alpha_to_rgb[(a<<8)+i] =
323
                                (((p->r * a / 31)>>3) << 10) |
324
                                (((p->g * a / 31)>>3) << 5) |
325
                                 ((p->b * a / 31)>>3);
326
                }
327
        }
328
 
329
        /*
330
         * Precompute RGB555 to palette index table by
331
         * finding the nearest palette index for all RGB555 colors.
332
         */
333
        for(r=0; r<32; ++r) {
334
                for(g=0; g<32; ++g)
335
                        for(b=0; b<32; ++b)
336
                                rgb_to_palindex[ (r<<10)|(g<<5)|b] =
337
                                        GdFindNearestColor(gr_palette, 256,
338
                                                MWRGB(r<<3, g<<3, b<<3));
339
        }
340
}
341
#endif
342
 
343
SUBDRIVER fblinear8 = {
344
        linear8_init,
345
        linear8_drawpixel,
346
        linear8_readpixel,
347
        linear8_drawhorzline,
348
        linear8_drawvertline,
349
        gen_fillrect,
350
        linear8_blit,
351
        NULL,
352
        linear8_stretchblit
353
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.