Subversion Repositories Games.Carmageddon

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 pmbaty 1
#include "pmmemops.h"
2
#include "harness/trace.h"
3
 
4
#include <string.h>
5
 
6
// FIXME: optimize filling memory, eventually using builtins
7
//        this file should contain a general arch-independent implementation,
8
//        other files can contain arch-specific implementations, e.g. one for SSE4
9
 
10
void pm_mem_fill_colour(br_uint_8* dest, br_uint_32 qual, br_uint_32 nbpixels, br_uint_32 bpp, br_uint_32 colour) {
11
    LOG_TRACE("(%p, %d, %d, %d, %d)", dest, qual, nbpixels, bpp, colour);
12
 
13
    switch (bpp) {
14
        case 1:
15
            memset(dest, colour, nbpixels);
16
            break;
17
        case 2: {
18
            br_uint_16 p = colour;
19
            int i;
20
            for (i = nbpixels; i != 0; i--, dest+=2) {
21
                *(br_uint_16*)dest = colour;
22
            }
23
            break;
24
        }
25
        break;
26
        case 3:
27
        case 4:
28
            NOT_IMPLEMENTED();
29
        default:
30
            TELL_ME_IF_WE_PASS_THIS_WAY();
31
            return;
32
    }
33
}
34
 
35
void pm_mem_fill_colour_rect(br_uint_8* dest, br_uint_32 qual, br_uint_32 width, br_uint_32 height, br_uint_32 stride, br_uint_32 bpp, br_uint_32 colour) {
36
    br_uint_32 x; // Pierre-Marie Baty -- fixed type
37
    br_uint_32 y; // Pierre-Marie Baty -- fixed type
38
    LOG_TRACE("(%p, %d, %d, %d, %d, %d, %d)", dest, qual, width, height, stride, bpp, colour);
39
 
40
    switch (bpp) {
41
    case 1:
42
        for (y = 0; y < height; y++) {
43
            memset(dest + y * stride, colour, width);
44
        }
45
        break;
46
    case 2:
47
        for (y = 0; y < height; y++) {
48
            for (x = 0; x < width; x+=1) {
49
                *(br_uint_16*)(dest + y * stride + 2 * x) = colour;
50
            }
51
        }
52
        break;
53
    case 3:
54
    case 4:
55
        NOT_IMPLEMENTED();
56
    default:
57
        TELL_ME_IF_WE_PASS_THIS_WAY();
58
        return;
59
    }
60
}
61
 
62
void pm_mem_copy_colour(br_uint_8* dest, br_uint_32 dest_qual, br_uint_8* src, br_uint_32 src_qual, br_uint_32 nbpixels, br_uint_32 bpp) {
63
    LOG_TRACE("(%p, %d, %p, %d, %d, %d)", dest, dest_qual, src, src_qual, nbpixels, bpp);
64
 
65
    memcpy(dest, src, nbpixels * bpp);
66
}
67
 
68
void pm_mem_copy_colour_rect(br_uint_8* dest, br_uint_32 dest_qual, br_uint_8* src ,br_uint_32 src_qual,
69
                 br_uint_32 width, br_uint_32 height, br_uint_32 dest_stride, br_uint_32 src_stride, br_uint_32 bpp) {
70
    br_uint_32 i; // Pierre-Marie Baty -- fixed type
71
    LOG_TRACE("(%p, %d, %p, %d, %d, %d, %d, %d, %d)", dest, dest_qual, src, src_qual, width, height, dest_stride, src_stride, bpp);
72
 
73
    for (i = 0; i < height; i++) {
74
        memcpy(dest + i * dest_stride, src + i * src_stride, bpp * width);
75
    }
76
}
77
 
78
void pm_mem_set_colour(br_uint_8* dest, br_uint_32 dest_qual, br_uint_32 bpp, br_uint_32 colour) {
79
    switch (bpp) {
80
    case 1:
81
        *(br_uint_8*)dest = colour;
82
        break;
83
    case 2:
84
        *(br_uint_16*)dest = colour;
85
        break;
86
    case 3:
87
        ((br_uint_8*)dest)[0] = colour;
88
        ((br_uint_8*)dest)[1] = colour >> 8;
89
        ((br_uint_8*)dest)[2] = colour >> 16;
90
        break;
91
    case 4:
92
        *(br_uint_32*)dest = colour;
93
        break;
94
    default:
95
        TELL_ME_IF_WE_PASS_THIS_WAY();
96
    }
97
}
98
 
99
void pm_mem_copy_bits(br_uint_8* dst, br_uint_32 dst_qual, br_uint_32 dst_stride, br_uint_8* src, br_uint_32 src_stride,
100
        br_uint_32 start_bit, br_uint_32 end_bit, br_uint_32 height, br_uint_32 bpp, br_uint_32 colour) {
101
    static br_uint_8 start_mask_lut[9] = { 0xff, 0x7f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0x1, 0x0 };
102
    static br_uint_8 end_mask_lut[9] = { 0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
103
    br_uint_8 start_mask;
104
    br_uint_8 end_mask;
105
    br_uint_32 end_bit_byte;
106
    br_uint_8 mask;
107
    br_uint_8 colour_byte1;
108
    br_uint_8 colour_byte2;
109
    br_uint_8 colour_byte3;
110
    br_uint_8* tmp_dst;
111
    br_uint_8* tmp_src;
112
    LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d, %d)", dst, dst_qual, dst_stride, src, src_stride, start_bit, end_bit, height, bpp, colour);
113
 
114
 
115
    start_mask = start_mask_lut[start_bit];
116
    end_mask = end_mask_lut[end_bit % 8];
117
    end_bit_byte = end_bit / 8;
118
 
119
    if (end_bit_byte == 0) {
120
        if (bpp == 1) {
121
            colour_byte1 = colour;
122
            for (; height != 0; height--, dst += dst_stride, src += src_stride) {
123
                mask = *src & start_mask & end_mask;
124
                if (mask & 0x80) {
125
                    dst[0] = colour_byte1;
126
                }
127
                if (mask & 0x40) {
128
                    dst[1] = colour_byte1;
129
                }
130
                if (mask & 0x20) {
131
                    dst[2] = colour_byte1;
132
                }
133
                if (mask & 0x10) {
134
                    dst[3] = colour_byte1;
135
                }
136
                if (mask & 0x08) {
137
                    dst[4] = colour_byte1;
138
                }
139
                if (mask & 0x04) {
140
                    dst[5] = colour_byte1;
141
                }
142
                if (mask & 0x02) {
143
                    dst[6] = colour_byte1;
144
                }
145
                if (mask & 0x01) {
146
                    dst[7] = colour_byte1;
147
                }
148
            }
149
            return;
150
        }
151
        else if (bpp == 2) {
152
            mask = *src & start_mask & end_mask;
153
            colour_byte1 = colour;
154
            colour_byte2 = colour >> 8;
155
            for (; height != 0; height--, dst += dst_stride, src += src_stride) {
156
                if (mask & 0x80) {
157
                    dst[0] = colour_byte1;
158
                    dst[1] = colour_byte2;
159
                }
160
                if (mask & 0x40) {
161
                    dst[2] = colour_byte1;
162
                    dst[3] = colour_byte2;
163
                }
164
                if (mask & 0x20) {
165
                    dst[4] = colour_byte1;
166
                    dst[5] = colour_byte2;
167
                }
168
                if (mask & 0x10) {
169
                    dst[6] = colour_byte1;
170
                    dst[7] = colour_byte2;
171
                }
172
                if (mask & 0x08) {
173
                    dst[8] = colour_byte1;
174
                    dst[9] = colour_byte2;
175
                }
176
                if (mask & 0x04) {
177
                    dst[10] = colour_byte1;
178
                    dst[11] = colour_byte2;
179
                }
180
                if (mask & 0x02) {
181
                    dst[12] = colour_byte1;
182
                    dst[13] = colour_byte2;
183
                }
184
                if (mask & 0x01) {
185
                    dst[14] = colour_byte1;
186
                    dst[15] = colour_byte2;
187
                }
188
            }
189
            return;
190
        }
191
        else if (bpp == 3) {
192
            mask = *src & start_mask & end_mask;
193
            colour_byte1 = colour;
194
            colour_byte2 = colour >> 8;
195
            colour_byte3 = colour >> 16;
196
            for (; height != 0; height--, dst += dst_stride, src += src_stride) {
197
                if (mask & 0x80) {
198
                    dst[0] = colour_byte1;
199
                    dst[1] = colour_byte2;
200
                    dst[2] = colour_byte3;
201
                }
202
                if (mask & 0x40) {
203
                    dst[3] = colour_byte1;
204
                    dst[4] = colour_byte2;
205
                    dst[5] = colour_byte3;
206
                }
207
                if (mask & 0x20) {
208
                    dst[6] = colour_byte1;
209
                    dst[7] = colour_byte2;
210
                    dst[8] = colour_byte3;
211
                }
212
                if (mask & 0x10) {
213
                    dst[9] = colour_byte1;
214
                    dst[10] = colour_byte2;
215
                    dst[11] = colour_byte3;
216
                }
217
                if (mask & 0x08) {
218
                    dst[12] = colour_byte1;
219
                    dst[13] = colour_byte2;
220
                    dst[14] = colour_byte3;
221
                }
222
                if (mask & 0x04) {
223
                    dst[15] = colour_byte1;
224
                    dst[16] = colour_byte2;
225
                    dst[17] = colour_byte3;
226
                }
227
                if (mask & 0x02) {
228
                    dst[18] = colour_byte1;
229
                    dst[19] = colour_byte2;
230
                    dst[20] = colour_byte3;
231
                }
232
                if (mask & 0x01) {
233
                    dst[21] = colour_byte1;
234
                    dst[22] = colour_byte2;
235
                    dst[23] = colour_byte3;
236
                }
237
            }
238
            return;
239
        }
240
        else if (bpp == 4) {
241
            mask = *src & start_mask & end_mask;
242
            for (; height != 0; height--, dst += dst_stride, src += src_stride) {
243
                if (mask & 0x80) {
244
                    ((br_uint_32*)dst)[0] = colour;
245
                }
246
                if (mask & 0x40) {
247
                    ((br_uint_32*)dst)[1] = colour;
248
                }
249
                if (mask & 0x20) {
250
                    ((br_uint_32*)dst)[2] = colour;
251
                }
252
                if (mask & 0x10) {
253
                    ((br_uint_32*)dst)[3] = colour;
254
                }
255
                if (mask & 0x08) {
256
                    ((br_uint_32*)dst)[4] = colour;
257
                }
258
                if (mask & 0x04) {
259
                    ((br_uint_32*)dst)[5] = colour;
260
                }
261
                if (mask & 0x02) {
262
                    ((br_uint_32*)dst)[6] = colour;
263
                }
264
                if (mask & 0x01) {
265
                    ((br_uint_32*)dst)[7] = colour;
266
                }
267
            }
268
            return;
269
        }
270
        else {
271
            return;
272
        }
273
    }
274
    if (bpp == 1) {
275
        colour_byte1 = colour;
276
 
277
        for (; height != 0; height--, src += src_stride, dst += dst_stride) {
278
            br_uint_8 row_end_bit_byte;
279
            mask = *src & start_mask;
280
            tmp_dst = dst;
281
            tmp_src = src;
282
            row_end_bit_byte = end_bit_byte;
283
            while (row_end_bit_byte != 0) {
284
                if (mask & 0x80) {
285
                    tmp_dst[0] = colour_byte1;
286
                }
287
                if (mask & 0x40) {
288
                    tmp_dst[1] = colour_byte1;
289
                }
290
                if (mask & 0x20) {
291
                    tmp_dst[2] = colour_byte1;
292
                }
293
                if (mask & 0x10) {
294
                    tmp_dst[3] = colour_byte1;
295
                }
296
                if (mask & 0x08) {
297
                    tmp_dst[4] = colour_byte1;
298
                }
299
                if (mask & 0x04) {
300
                    tmp_dst[5] = colour_byte1;
301
                }
302
                if (mask & 0x02) {
303
                    tmp_dst[6] = colour_byte1;
304
                }
305
                if (mask & 0x01) {
306
                    tmp_dst[7] = colour_byte1;
307
                }
308
                tmp_dst += 8;
309
                tmp_src += 1;
310
                row_end_bit_byte -= 1;
311
                mask = *tmp_src;
312
            }
313
            mask = end_mask;
314
            if (mask & 0x80) {
315
                tmp_dst[0] = colour_byte1;
316
            }
317
            if (mask & 0x40) {
318
                tmp_dst[1] = colour_byte1;
319
            }
320
            if (mask & 0x20) {
321
                tmp_dst[2] = colour_byte1;
322
            }
323
            if (mask & 0x10) {
324
                tmp_dst[3] = colour_byte1;
325
            }
326
            if (mask & 0x08) {
327
                tmp_dst[4] = colour_byte1;
328
            }
329
            if (mask & 0x04) {
330
                tmp_dst[5] = colour_byte1;
331
            }
332
            if (mask & 0x02) {
333
                tmp_dst[6] = colour_byte1;
334
            }
335
            if (mask & 0x01) {
336
                tmp_dst[7] = colour_byte1;
337
            }
338
        }
339
        return;
340
    } else {
341
        TELL_ME_IF_WE_PASS_THIS_WAY();
342
    }
343
}