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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [mw/] [src/] [drivers/] [fblin8.c] - Blame information for rev 1773

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

powered by: WebSVN 2.1.0

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