~ubuntu-branches/ubuntu/oneiric/libmng/oneiric

« back to all changes in this revision

Viewing changes to contrib/gcc/fbmngplay/mng.c

  • Committer: Bazaar Package Importer
  • Author(s): Shiju p. Nair
  • Date: 2006-04-07 09:49:11 UTC
  • mfrom: (0.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060407094911-ay3179o63gvlh4ll
Tags: 1.0.9-1
* New upstream release. (closes: #303968, #271979)
* Patch from Aurelien Jarno <aurel32@debian.org> to support GNU/kFreeBSD.
  Closes: #314696)
* Patch from Christopher Bodenstein <cb@physicman.net> to support
  hurd-i386. (closes: #361103)
* README.Debian provide information on what options are compiled in to
  libmng.(closes: #174523)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
        fbmngplay - fb console MNG player.
3
 
        (c) 2001 by Stefan Reinauer, <stepan :at: suse.de>
4
 
 
5
 
        This program is based on mngplay, part of libmng, written and (C) by
6
 
        Ralph Giles <giles :at: ashlu.bc.ca>
7
 
 
8
 
        This program my be redistributed under the terms of the
9
 
        GNU General Public Licence, version 2, or at your preference,
10
 
        any later version.
11
 
*/
12
 
 
13
 
#include <unistd.h>
14
 
#include <sys/time.h>
15
 
#include <linux/vt.h>
16
 
 
17
 
#include "fbmngplay.h"
18
 
#include "console.h"
19
 
#include "mng.h"
20
 
 
21
 
mngstuff *mng;
22
 
unsigned char *bufferstream;
23
 
unsigned long bufferpos = 0, buffersize = 0;
24
 
 
25
 
inline void mdelay(unsigned long msec)
26
 
{
27
 
        usleep(msec * 1000);
28
 
}
29
 
 
30
 
/* callbacks for the mng decoder */
31
 
 
32
 
/* memory allocation; data must be zeroed */
33
 
mng_ptr mngalloc(mng_uint32 size)
34
 
{
35
 
        return (mng_ptr) calloc(1, size);
36
 
}
37
 
 
38
 
/* memory deallocation */
39
 
void mngfree(mng_ptr p, mng_uint32 size)
40
 
{
41
 
        free(p);
42
 
        return;
43
 
}
44
 
 
45
 
mng_bool mngopenstream(mng_handle mng)
46
 
{
47
 
        mngstuff *mymng;
48
 
 
49
 
        /* look up our stream struct */
50
 
        mymng = (mngstuff *) mng_get_userdata(mng);
51
 
 
52
 
        /* open the file */
53
 
        mymng->file = fopen(mymng->filename, "rb");
54
 
        if (mymng->file == NULL) {
55
 
                fprintf(stderr, "unable to open '%s'\n", mymng->filename);
56
 
                run = 0;
57
 
                return MNG_FALSE;
58
 
        }
59
 
 
60
 
        if (buffered) {
61
 
                unsigned long len;
62
 
                fseek(mymng->file, 0, SEEK_END);
63
 
                len = ftell(mymng->file);
64
 
                rewind(mymng->file);
65
 
                bufferstream = malloc(len);
66
 
                if (!bufferstream) {
67
 
                        /* Not enough memory for buffers 
68
 
                         * -> we go back to unbuffered mode
69
 
                         */
70
 
                        printf("Reverted to non buffered mode.\n");
71
 
                        buffered = 0;
72
 
                        return MNG_TRUE;
73
 
                }
74
 
                buffersize = len;
75
 
                fread(bufferstream, 1, len, mymng->file);
76
 
                bufferpos = 0;
77
 
                fclose(mymng->file);
78
 
                mymng->file = NULL;
79
 
        }
80
 
 
81
 
        return MNG_TRUE;
82
 
}
83
 
 
84
 
mng_bool mngclosestream(mng_handle mng)
85
 
{
86
 
        mngstuff *mymng;
87
 
 
88
 
        /* look up our stream struct */
89
 
        mymng = (mngstuff *) mng_get_userdata(mng);
90
 
 
91
 
        /* close the file */
92
 
        if (mymng->file)
93
 
                fclose(mymng->file);
94
 
        mymng->file = NULL;     /* for safety */
95
 
 
96
 
        if (bufferstream) {
97
 
                free(bufferstream);
98
 
                bufferstream = 0;
99
 
                buffersize = 0;
100
 
                bufferpos = 0;
101
 
        }
102
 
        return MNG_TRUE;
103
 
}
104
 
 
105
 
/* feed data to the decoder */
106
 
mng_bool mngreadstream(mng_handle mng, mng_ptr buffer,
107
 
                         mng_uint32 size, mng_uint32 * bytesread)
108
 
{
109
 
        mngstuff *mymng;
110
 
 
111
 
        /* look up our stream struct */
112
 
        mymng = (mngstuff *) mng_get_userdata(mng);
113
 
        if (!buffered) {
114
 
                /* read the requested amount of data from the file */
115
 
                *bytesread = fread(buffer, 1, size, mymng->file);
116
 
        } else {
117
 
                *bytesread = (buffersize - bufferpos) <
118
 
                    size ? (buffersize - bufferpos) : size;
119
 
                memcpy(buffer, bufferstream + bufferpos, *bytesread);
120
 
                bufferpos += (*bytesread);
121
 
        }
122
 
        return MNG_TRUE;
123
 
}
124
 
 
125
 
/* the header's been read. set up the display stuff */
126
 
mng_bool mngprocessheader(mng_handle mng,
127
 
                            mng_uint32 width, mng_uint32 height)
128
 
{
129
 
        mngstuff *mymng;
130
 
        unsigned char *copybuffer, *background;
131
 
        unsigned char *src;
132
 
 
133
 
        mymng = (mngstuff *) mng_get_userdata(mng);
134
 
        mymng->width = width;
135
 
        mymng->height = height;
136
 
 
137
 
        if (dynpos) {
138
 
                mymng->fbx = (mymng->fbwidth)-width-15;
139
 
                switch (mymng->fbheight) {
140
 
                case 768:
141
 
                        mymng->fby = 15;
142
 
                        break;
143
 
                case 1024:
144
 
                        mymng->fby = 30;
145
 
                        break;
146
 
                default:
147
 
                        mymng->fby = 0;
148
 
                        break;
149
 
                }
150
 
        }
151
 
 
152
 
        copybuffer = (unsigned char *) malloc(width * height * 4);
153
 
        if (copybuffer == NULL) {
154
 
                fprintf(stderr, "could not allocate copy buffer.\n");
155
 
                exit(0);
156
 
        }
157
 
        mymng->copybuffer = copybuffer;
158
 
 
159
 
        if (!mymng->background) {
160
 
                background =
161
 
                    (unsigned char *) malloc(width * height *
162
 
                                             (mymng->fbbpp >> 3));
163
 
                if (background == NULL) {
164
 
                        fprintf(stderr,
165
 
                                "could not allocate background buffer.\n");
166
 
                        exit(0);
167
 
                }
168
 
                mymng->background = background;
169
 
 
170
 
                src = mymng->display + (mymng->fbwidth * mymng->fby +
171
 
                                      mymng->fbx) * (mymng->fbbpp >> 3);
172
 
 
173
 
                while (height--) {
174
 
                        memcpy(background, src,
175
 
                               width * (mymng->fbbpp >> 3));
176
 
                        background += width * (mymng->fbbpp >> 3);
177
 
                        src += mymng->fbwidth * (mymng->fbbpp >> 3);
178
 
                }
179
 
        }
180
 
        /* tell the mng decoder about our bit-depth choice */
181
 
        /* FIXME: this works on intel. is it correct in general? */
182
 
        mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8);
183
 
 
184
 
        return MNG_TRUE;
185
 
}
186
 
 
187
 
/* return a row pointer for the decoder to fill */
188
 
mng_ptr mnggetcanvasline(mng_handle mng, mng_uint32 line)
189
 
{
190
 
        mngstuff *mymng;
191
 
        mng_ptr row;
192
 
 
193
 
        /* dereference our structure */
194
 
        mymng = (mngstuff *) mng_get_userdata(mng);
195
 
 
196
 
        /* we assume any necessary locking has happened 
197
 
           outside, in the frame level code */
198
 
        row = mymng->copybuffer + mymng->width * 4 * line;
199
 
 
200
 
        return (row);
201
 
}
202
 
 
203
 
/* timer */
204
 
mng_uint32 mnggetticks(mng_handle mng)
205
 
{
206
 
        mng_uint32 ticks;
207
 
        struct timeval tv;
208
 
        struct timezone tz;
209
 
 
210
 
        gettimeofday(&tv, &tz);
211
 
        ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
212
 
 
213
 
        return (ticks);
214
 
}
215
 
 
216
 
static inline void copyline(unsigned char *dest, unsigned char *src,
217
 
                     unsigned char *background, mngstuff * mymng)
218
 
{
219
 
        // BGRA8        
220
 
        unsigned int i = mymng->width;
221
 
        unsigned int fr, fg, fb, br, bg, bb, r, g, b, a;
222
 
        unsigned short output, input;
223
 
 
224
 
        while (i--) {
225
 
                fb = *src++;
226
 
                fg = *src++;
227
 
                fr = *src++;
228
 
 
229
 
                a = *src++;
230
 
                a = a * mymng->alpha / 100;
231
 
                switch (mymng->fbbpp) {
232
 
                case 16:
233
 
                        input = *((unsigned short *) background)++;
234
 
                        br = (input >> 8) & 0xf8;
235
 
                        bg = (input >> 3) & 0xfc;
236
 
                        bb = input << 3 & 0xff;
237
 
                        break;
238
 
                case 24:
239
 
                        bb = *background++;
240
 
                        bg = *background++;
241
 
                        br = *background++;
242
 
                        break;
243
 
                case 32:
244
 
                        bb = *background++;
245
 
                        bg = *background++;
246
 
                        br = *background++;
247
 
                        background++;
248
 
                        break;
249
 
                default:
250
 
                        br = 0;
251
 
                        bg = 0;
252
 
                        bb = 0;
253
 
                        printf("depth not supported.\n");
254
 
                        run = 0;
255
 
                        break;
256
 
                }
257
 
 
258
 
                r = ((fr * a) + (br * (0x100 - a))) >> 8;
259
 
                g = ((fg * a) + (bg * (0x100 - a))) >> 8;
260
 
                b = ((fb * a) + (bb * (0x100 - a))) >> 8;
261
 
 
262
 
                switch (mymng->fbbpp) {
263
 
                case 16:
264
 
                        // dumb 24->16 bit conversion.
265
 
                        r >>= 3;
266
 
                        g >>= 2;
267
 
                        b >>= 3;
268
 
 
269
 
                        output = (r << 11) | (g << 5) | b;
270
 
                        *((unsigned short *) dest)++ = output;
271
 
                        break;
272
 
                case 24:
273
 
                        *dest++ = b;
274
 
                        *dest++ = g;
275
 
                        *dest++ = r;
276
 
                        break;
277
 
                case 32:
278
 
                        *dest++ = b;
279
 
                        *dest++ = g;
280
 
                        *dest++ = r;
281
 
                        dest++;
282
 
                        break;
283
 
                default:
284
 
                        break;
285
 
                }
286
 
        }
287
 
}
288
 
 
289
 
mng_bool mngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
290
 
                      mng_uint32 w, mng_uint32 h)
291
 
{
292
 
        mngstuff *mymng;
293
 
        unsigned char *dest, *src, *background;
294
 
 
295
 
        if (sconly && current_console()!=start_console)
296
 
                return MNG_TRUE;
297
 
        
298
 
        /* dereference our structure */
299
 
        mymng = (mngstuff *) mng_get_userdata(mng);
300
 
 
301
 
        dest = mymng->display + ((mymng->fby * mymng->fbwidth + mymng->fbx)
302
 
                                 * (mymng->fbbpp >> 3));
303
 
        src = mymng->copybuffer;
304
 
        background = mymng->background;
305
 
        /* refresh the screen with the new frame */
306
 
        while (h-- > 0) {
307
 
                copyline(dest, src, background, mymng);
308
 
                dest += mymng->fbwidth * (mymng->fbbpp >> 3);
309
 
                background += mymng->width * (mymng->fbbpp >> 3);
310
 
                src += 4 * mymng->width;        // 4 bytes per pixel due to RGBA
311
 
        }
312
 
 
313
 
        // remove traces
314
 
        memset(mymng->copybuffer, 0, 4 * mymng->width * mymng->height);
315
 
 
316
 
        return MNG_TRUE;
317
 
}
318
 
 
319
 
/* interframe delay callback */
320
 
mng_bool mngsettimer(mng_handle mng, mng_uint32 msecs)
321
 
{
322
 
        mngstuff *mymng;
323
 
 
324
 
        /* look up our stream struct */
325
 
        mymng = (mngstuff *) mng_get_userdata(mng);
326
 
 
327
 
        /* set the timer for when the decoder wants to be woken */
328
 
        mymng->delay = msecs;
329
 
 
330
 
        return MNG_TRUE;
331
 
}
332
 
 
333
 
mng_bool mngerror(mng_handle mng, mng_int32 code, mng_int8 severity,
334
 
                    mng_chunkid chunktype, mng_uint32 chunkseq,
335
 
                    mng_int32 extra1, mng_int32 extra2, mng_pchar text)
336
 
{
337
 
        mngstuff *mymng;
338
 
        char chunk[5];
339
 
 
340
 
        /* dereference our data so we can get the filename */
341
 
        mymng = (mngstuff *) mng_get_userdata(mng);
342
 
        /* pull out the chuck type as a string */
343
 
        // FIXME: does this assume unsigned char?
344
 
        chunk[0] = (char) ((chunktype >> 24) & 0xFF);
345
 
        chunk[1] = (char) ((chunktype >> 16) & 0xFF);
346
 
        chunk[2] = (char) ((chunktype >> 8) & 0xFF);
347
 
        chunk[3] = (char) ((chunktype) & 0xFF);
348
 
        chunk[4] = '\0';
349
 
 
350
 
        /* output the error */
351
 
        fprintf(stderr, "error playing '%s' chunk %s (%d):\n",
352
 
                mymng->filename, chunk, chunkseq);
353
 
        fprintf(stderr, "%s\n", text);
354
 
 
355
 
        return 0;
356
 
}
357
 
 
358
 
int mngquit(mng_handle mng)
359
 
{
360
 
        mngstuff *mymng;
361
 
 
362
 
        /* dereference our data so we can free it */
363
 
        mymng = (mngstuff *) mng_get_userdata(mng);
364
 
 
365
 
        /* cleanup. this will call mymngclosestream */
366
 
        mng_cleanup(&mng);
367
 
 
368
 
        /* free our data */
369
 
        free(mymng);
370
 
        /* quit */
371
 
        exit(0);
372
 
}
373
 
 
374
 
void cleanup(void)
375
 
{
376
 
        mngquit(mng->mng);
377
 
        exit(0);
378
 
}
379
 
 
380
 
void restore_area(void)
381
 
{
382
 
        int height, width;
383
 
        unsigned char *dest, *background;
384
 
 
385
 
        if (sconly && current_console()!=start_console)
386
 
                return;
387
 
        
388
 
        background = mng->background;
389
 
        height = mng->height;
390
 
        width = mng->width;
391
 
        dest = mng->display + (mng->fbwidth * mng->fby +
392
 
                               mng->fbx) * (mng->fbbpp >> 3);
393
 
        while (height--) {
394
 
                memcpy(dest, background, width * (mng->fbbpp >> 3));
395
 
                background += width * (mng->fbbpp >> 3);
396
 
                dest += mng->fbwidth * (mng->fbbpp >> 3);
397
 
        }
398
 
}
 
1
/*
 
2
        fbmngplay - fb console MNG player.
 
3
        (c) 2001 by Stefan Reinauer, <stepan :at: suse.de>
 
4
 
 
5
        This program is based on mngplay, part of libmng, written and (C) by
 
6
        Ralph Giles <giles :at: ashlu.bc.ca>
 
7
 
 
8
        This program my be redistributed under the terms of the
 
9
        GNU General Public Licence, version 2, or at your preference,
 
10
        any later version.
 
11
*/
 
12
 
 
13
#include <unistd.h>
 
14
#include <sys/time.h>
 
15
#include <linux/vt.h>
 
16
 
 
17
#include "fbmngplay.h"
 
18
#include "console.h"
 
19
#include "mng.h"
 
20
 
 
21
mngstuff *mng;
 
22
unsigned char *bufferstream;
 
23
unsigned long bufferpos = 0, buffersize = 0;
 
24
 
 
25
inline void mdelay(unsigned long msec)
 
26
{
 
27
        usleep(msec * 1000);
 
28
}
 
29
 
 
30
/* callbacks for the mng decoder */
 
31
 
 
32
/* memory allocation; data must be zeroed */
 
33
mng_ptr mngalloc(mng_uint32 size)
 
34
{
 
35
        return (mng_ptr) calloc(1, size);
 
36
}
 
37
 
 
38
/* memory deallocation */
 
39
void mngfree(mng_ptr p, mng_uint32 size)
 
40
{
 
41
        free(p);
 
42
        return;
 
43
}
 
44
 
 
45
mng_bool mngopenstream(mng_handle mng)
 
46
{
 
47
        mngstuff *mymng;
 
48
 
 
49
        /* look up our stream struct */
 
50
        mymng = (mngstuff *) mng_get_userdata(mng);
 
51
 
 
52
        /* open the file */
 
53
        mymng->file = fopen(mymng->filename, "rb");
 
54
        if (mymng->file == NULL) {
 
55
                fprintf(stderr, "unable to open '%s'\n", mymng->filename);
 
56
                run = 0;
 
57
                return MNG_FALSE;
 
58
        }
 
59
 
 
60
        if (buffered) {
 
61
                unsigned long len;
 
62
                fseek(mymng->file, 0, SEEK_END);
 
63
                len = ftell(mymng->file);
 
64
                rewind(mymng->file);
 
65
                bufferstream = malloc(len);
 
66
                if (!bufferstream) {
 
67
                        /* Not enough memory for buffers 
 
68
                         * -> we go back to unbuffered mode
 
69
                         */
 
70
                        printf("Reverted to non buffered mode.\n");
 
71
                        buffered = 0;
 
72
                        return MNG_TRUE;
 
73
                }
 
74
                buffersize = len;
 
75
                fread(bufferstream, 1, len, mymng->file);
 
76
                bufferpos = 0;
 
77
                fclose(mymng->file);
 
78
                mymng->file = NULL;
 
79
        }
 
80
 
 
81
        return MNG_TRUE;
 
82
}
 
83
 
 
84
mng_bool mngclosestream(mng_handle mng)
 
85
{
 
86
        mngstuff *mymng;
 
87
 
 
88
        /* look up our stream struct */
 
89
        mymng = (mngstuff *) mng_get_userdata(mng);
 
90
 
 
91
        /* close the file */
 
92
        if (mymng->file)
 
93
                fclose(mymng->file);
 
94
        mymng->file = NULL;     /* for safety */
 
95
 
 
96
        if (bufferstream) {
 
97
                free(bufferstream);
 
98
                bufferstream = 0;
 
99
                buffersize = 0;
 
100
                bufferpos = 0;
 
101
        }
 
102
        return MNG_TRUE;
 
103
}
 
104
 
 
105
/* feed data to the decoder */
 
106
mng_bool mngreadstream(mng_handle mng, mng_ptr buffer,
 
107
                         mng_uint32 size, mng_uint32 * bytesread)
 
108
{
 
109
        mngstuff *mymng;
 
110
 
 
111
        /* look up our stream struct */
 
112
        mymng = (mngstuff *) mng_get_userdata(mng);
 
113
        if (!buffered) {
 
114
                /* read the requested amount of data from the file */
 
115
                *bytesread = fread(buffer, 1, size, mymng->file);
 
116
        } else {
 
117
                *bytesread = (buffersize - bufferpos) <
 
118
                    size ? (buffersize - bufferpos) : size;
 
119
                memcpy(buffer, bufferstream + bufferpos, *bytesread);
 
120
                bufferpos += (*bytesread);
 
121
        }
 
122
        return MNG_TRUE;
 
123
}
 
124
 
 
125
/* the header's been read. set up the display stuff */
 
126
mng_bool mngprocessheader(mng_handle mng,
 
127
                            mng_uint32 width, mng_uint32 height)
 
128
{
 
129
        mngstuff *mymng;
 
130
        unsigned char *copybuffer, *background;
 
131
        unsigned char *src;
 
132
 
 
133
        mymng = (mngstuff *) mng_get_userdata(mng);
 
134
        mymng->width = width;
 
135
        mymng->height = height;
 
136
 
 
137
        if (dynpos) {
 
138
                mymng->fbx = (mymng->fbwidth)-width-15;
 
139
                switch (mymng->fbheight) {
 
140
                case 768:
 
141
                        mymng->fby = 15;
 
142
                        break;
 
143
                case 1024:
 
144
                        mymng->fby = 30;
 
145
                        break;
 
146
                default:
 
147
                        mymng->fby = 0;
 
148
                        break;
 
149
                }
 
150
        }
 
151
 
 
152
        copybuffer = (unsigned char *) malloc(width * height * 4);
 
153
        if (copybuffer == NULL) {
 
154
                fprintf(stderr, "could not allocate copy buffer.\n");
 
155
                exit(0);
 
156
        }
 
157
        mymng->copybuffer = copybuffer;
 
158
 
 
159
        if (!mymng->background) {
 
160
                background =
 
161
                    (unsigned char *) malloc(width * height *
 
162
                                             (mymng->fbbpp >> 3));
 
163
                if (background == NULL) {
 
164
                        fprintf(stderr,
 
165
                                "could not allocate background buffer.\n");
 
166
                        exit(0);
 
167
                }
 
168
                mymng->background = background;
 
169
 
 
170
                src = mymng->display + (mymng->fbwidth * mymng->fby +
 
171
                                      mymng->fbx) * (mymng->fbbpp >> 3);
 
172
 
 
173
                while (height--) {
 
174
                        memcpy(background, src,
 
175
                               width * (mymng->fbbpp >> 3));
 
176
                        background += width * (mymng->fbbpp >> 3);
 
177
                        src += mymng->fbwidth * (mymng->fbbpp >> 3);
 
178
                }
 
179
        }
 
180
        /* tell the mng decoder about our bit-depth choice */
 
181
        /* FIXME: this works on intel. is it correct in general? */
 
182
        mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8);
 
183
 
 
184
        return MNG_TRUE;
 
185
}
 
186
 
 
187
/* return a row pointer for the decoder to fill */
 
188
mng_ptr mnggetcanvasline(mng_handle mng, mng_uint32 line)
 
189
{
 
190
        mngstuff *mymng;
 
191
        mng_ptr row;
 
192
 
 
193
        /* dereference our structure */
 
194
        mymng = (mngstuff *) mng_get_userdata(mng);
 
195
 
 
196
        /* we assume any necessary locking has happened 
 
197
           outside, in the frame level code */
 
198
        row = mymng->copybuffer + mymng->width * 4 * line;
 
199
 
 
200
        return (row);
 
201
}
 
202
 
 
203
/* timer */
 
204
mng_uint32 mnggetticks(mng_handle mng)
 
205
{
 
206
        mng_uint32 ticks;
 
207
        struct timeval tv;
 
208
        struct timezone tz;
 
209
 
 
210
        gettimeofday(&tv, &tz);
 
211
        ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
 
212
 
 
213
        return (ticks);
 
214
}
 
215
 
 
216
static inline void copyline(unsigned char *dest, unsigned char *src,
 
217
                     unsigned char *background, mngstuff * mymng)
 
218
{
 
219
        // BGRA8        
 
220
        unsigned int i = mymng->width;
 
221
        unsigned int fr, fg, fb, br, bg, bb, r, g, b, a;
 
222
        unsigned short output, input;
 
223
 
 
224
        while (i--) {
 
225
                fb = *src++;
 
226
                fg = *src++;
 
227
                fr = *src++;
 
228
 
 
229
                a = *src++;
 
230
                a = a * mymng->alpha / 100;
 
231
                switch (mymng->fbbpp) {
 
232
                case 16:
 
233
                        input = *((unsigned short *) background)++;
 
234
                        br = (input >> 8) & 0xf8;
 
235
                        bg = (input >> 3) & 0xfc;
 
236
                        bb = input << 3 & 0xff;
 
237
                        break;
 
238
                case 24:
 
239
                        bb = *background++;
 
240
                        bg = *background++;
 
241
                        br = *background++;
 
242
                        break;
 
243
                case 32:
 
244
                        bb = *background++;
 
245
                        bg = *background++;
 
246
                        br = *background++;
 
247
                        background++;
 
248
                        break;
 
249
                default:
 
250
                        br = 0;
 
251
                        bg = 0;
 
252
                        bb = 0;
 
253
                        printf("depth not supported.\n");
 
254
                        run = 0;
 
255
                        break;
 
256
                }
 
257
 
 
258
                r = ((fr * a) + (br * (0x100 - a))) >> 8;
 
259
                g = ((fg * a) + (bg * (0x100 - a))) >> 8;
 
260
                b = ((fb * a) + (bb * (0x100 - a))) >> 8;
 
261
 
 
262
                switch (mymng->fbbpp) {
 
263
                case 16:
 
264
                        // dumb 24->16 bit conversion.
 
265
                        r >>= 3;
 
266
                        g >>= 2;
 
267
                        b >>= 3;
 
268
 
 
269
                        output = (r << 11) | (g << 5) | b;
 
270
                        *((unsigned short *) dest)++ = output;
 
271
                        break;
 
272
                case 24:
 
273
                        *dest++ = b;
 
274
                        *dest++ = g;
 
275
                        *dest++ = r;
 
276
                        break;
 
277
                case 32:
 
278
                        *dest++ = b;
 
279
                        *dest++ = g;
 
280
                        *dest++ = r;
 
281
                        dest++;
 
282
                        break;
 
283
                default:
 
284
                        break;
 
285
                }
 
286
        }
 
287
}
 
288
 
 
289
mng_bool mngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y,
 
290
                      mng_uint32 w, mng_uint32 h)
 
291
{
 
292
        mngstuff *mymng;
 
293
        unsigned char *dest, *src, *background;
 
294
 
 
295
        if (sconly && current_console()!=start_console)
 
296
                return MNG_TRUE;
 
297
        
 
298
        /* dereference our structure */
 
299
        mymng = (mngstuff *) mng_get_userdata(mng);
 
300
 
 
301
        dest = mymng->display + ((mymng->fby * mymng->fbwidth + mymng->fbx)
 
302
                                 * (mymng->fbbpp >> 3));
 
303
        src = mymng->copybuffer;
 
304
        background = mymng->background;
 
305
        /* refresh the screen with the new frame */
 
306
        while (h-- > 0) {
 
307
                copyline(dest, src, background, mymng);
 
308
                dest += mymng->fbwidth * (mymng->fbbpp >> 3);
 
309
                background += mymng->width * (mymng->fbbpp >> 3);
 
310
                src += 4 * mymng->width;        // 4 bytes per pixel due to RGBA
 
311
        }
 
312
 
 
313
        // remove traces
 
314
        memset(mymng->copybuffer, 0, 4 * mymng->width * mymng->height);
 
315
 
 
316
        return MNG_TRUE;
 
317
}
 
318
 
 
319
/* interframe delay callback */
 
320
mng_bool mngsettimer(mng_handle mng, mng_uint32 msecs)
 
321
{
 
322
        mngstuff *mymng;
 
323
 
 
324
        /* look up our stream struct */
 
325
        mymng = (mngstuff *) mng_get_userdata(mng);
 
326
 
 
327
        /* set the timer for when the decoder wants to be woken */
 
328
        mymng->delay = msecs;
 
329
 
 
330
        return MNG_TRUE;
 
331
}
 
332
 
 
333
mng_bool mngerror(mng_handle mng, mng_int32 code, mng_int8 severity,
 
334
                    mng_chunkid chunktype, mng_uint32 chunkseq,
 
335
                    mng_int32 extra1, mng_int32 extra2, mng_pchar text)
 
336
{
 
337
        mngstuff *mymng;
 
338
        char chunk[5];
 
339
 
 
340
        /* dereference our data so we can get the filename */
 
341
        mymng = (mngstuff *) mng_get_userdata(mng);
 
342
        /* pull out the chuck type as a string */
 
343
        // FIXME: does this assume unsigned char?
 
344
        chunk[0] = (char) ((chunktype >> 24) & 0xFF);
 
345
        chunk[1] = (char) ((chunktype >> 16) & 0xFF);
 
346
        chunk[2] = (char) ((chunktype >> 8) & 0xFF);
 
347
        chunk[3] = (char) ((chunktype) & 0xFF);
 
348
        chunk[4] = '\0';
 
349
 
 
350
        /* output the error */
 
351
        fprintf(stderr, "error playing '%s' chunk %s (%d):\n",
 
352
                mymng->filename, chunk, chunkseq);
 
353
        fprintf(stderr, "%s\n", text);
 
354
 
 
355
        return 0;
 
356
}
 
357
 
 
358
int mngquit(mng_handle mng)
 
359
{
 
360
        mngstuff *mymng;
 
361
 
 
362
        /* dereference our data so we can free it */
 
363
        mymng = (mngstuff *) mng_get_userdata(mng);
 
364
 
 
365
        /* cleanup. this will call mymngclosestream */
 
366
        mng_cleanup(&mng);
 
367
 
 
368
        /* free our data */
 
369
        free(mymng);
 
370
        /* quit */
 
371
        exit(0);
 
372
}
 
373
 
 
374
void cleanup(void)
 
375
{
 
376
        mngquit(mng->mng);
 
377
        exit(0);
 
378
}
 
379
 
 
380
void restore_area(void)
 
381
{
 
382
        int height, width;
 
383
        unsigned char *dest, *background;
 
384
 
 
385
        if (sconly && current_console()!=start_console)
 
386
                return;
 
387
        
 
388
        background = mng->background;
 
389
        height = mng->height;
 
390
        width = mng->width;
 
391
        dest = mng->display + (mng->fbwidth * mng->fby +
 
392
                               mng->fbx) * (mng->fbbpp >> 3);
 
393
        while (height--) {
 
394
                memcpy(dest, background, width * (mng->fbbpp >> 3));
 
395
                background += width * (mng->fbbpp >> 3);
 
396
                dest += mng->fbwidth * (mng->fbbpp >> 3);
 
397
        }
 
398
}