~ubuntu-branches/ubuntu/raring/scummvm/raring

« back to all changes in this revision

Viewing changes to video/mpeg_player.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: (21.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ScummVM - Graphic Adventure Engine
 
2
 *
 
3
 * ScummVM is the legal property of its developers, whose names
 
4
 * are too numerous to list here. Please refer to the COPYRIGHT
 
5
 * file distributed with this source distribution.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2
 
10
 * of the License, or (at your option) any later version.
 
11
 
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
20
 *
 
21
 * $URL$
 
22
 * $Id$
 
23
 *
 
24
 */
 
25
 
 
26
// The YUV to RGB conversion code is derived from SDL's YUV overlay code, which
 
27
// in turn appears to be derived from mpeg_play. The following copyright
 
28
// notices have been included in accordance with the original license. Please
 
29
// note that the term "software" in this context only applies to the
 
30
// buildLookup() and plotYUV*() functions below.
 
31
 
 
32
// Copyright (c) 1995 The Regents of the University of California.
 
33
// All rights reserved.
 
34
//
 
35
// Permission to use, copy, modify, and distribute this software and its
 
36
// documentation for any purpose, without fee, and without written agreement is
 
37
// hereby granted, provided that the above copyright notice and the following
 
38
// two paragraphs appear in all copies of this software.
 
39
//
 
40
// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 
41
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 
42
// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 
43
// CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
44
//
 
45
// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 
46
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 
47
// AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 
48
// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 
49
// PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
50
 
 
51
// Copyright (c) 1995 Erik Corry
 
52
// All rights reserved.
 
53
//
 
54
// Permission to use, copy, modify, and distribute this software and its
 
55
// documentation for any purpose, without fee, and without written agreement is
 
56
// hereby granted, provided that the above copyright notice and the following
 
57
// two paragraphs appear in all copies of this software.
 
58
//
 
59
// IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 
60
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
 
61
// THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
 
62
// OF THE POSSIBILITY OF SUCH DAMAGE.
 
63
//
 
64
// ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 
65
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
66
// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
 
67
// BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
 
68
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
69
 
 
70
// Portions of this software Copyright (c) 1995 Brown University.
 
71
// All rights reserved.
 
72
//
 
73
// Permission to use, copy, modify, and distribute this software and its
 
74
// documentation for any purpose, without fee, and without written agreement
 
75
// is hereby granted, provided that the above copyright notice and the
 
76
// following two paragraphs appear in all copies of this software.
 
77
//
 
78
// IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
 
79
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 
80
// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
 
81
// UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
82
//
 
83
// BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 
84
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
85
// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
 
86
// BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
 
87
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
88
 
 
89
#include "video/mpeg_player.h"
 
90
#include "common/file.h"
 
91
#include "common/system.h"
 
92
#include "common/util.h"
 
93
 
 
94
namespace Video {
 
95
 
 
96
BaseAnimationState::BaseAnimationState(OSystem *sys, int width, int height)
 
97
        : _movieWidth(width), _movieHeight(height), _frameWidth(width), _frameHeight(height), _sys(sys) {
 
98
#ifndef BACKEND_8BIT
 
99
        const int screenW = _sys->getOverlayWidth();
 
100
        const int screenH = _sys->getOverlayHeight();
 
101
 
 
102
        _movieScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
 
103
 
 
104
        assert(_movieScale >= 1);
 
105
        if (_movieScale > 3)
 
106
                _movieScale = 3;
 
107
 
 
108
        _colorTab = NULL;
 
109
        _rgbToPix = NULL;
 
110
        memset(&_overlayFormat, 0, sizeof(_overlayFormat));
 
111
#endif
 
112
}
 
113
 
 
114
BaseAnimationState::~BaseAnimationState() {
 
115
#ifdef USE_MPEG2
 
116
        if (_mpegDecoder)
 
117
                mpeg2_close(_mpegDecoder);
 
118
        delete _mpegFile;
 
119
#ifndef BACKEND_8BIT
 
120
        _sys->hideOverlay();
 
121
        free(_overlay);
 
122
        free(_colorTab);
 
123
        free(_rgbToPix);
 
124
#endif
 
125
#endif
 
126
}
 
127
 
 
128
 
 
129
bool BaseAnimationState::init(const char *name) {
 
130
#ifdef USE_MPEG2
 
131
        char tempFile[512];
 
132
 
 
133
        _mpegDecoder = NULL;
 
134
        _mpegFile = NULL;
 
135
 
 
136
#ifdef BACKEND_8BIT
 
137
 
 
138
        uint i, p;
 
139
 
 
140
        // Load lookup palettes
 
141
        sprintf(tempFile, "%s.pal", name);
 
142
 
 
143
        Common::File f;
 
144
 
 
145
        if (!f.open(tempFile)) {
 
146
                warning("Cutscene: %s palette missing", tempFile);
 
147
                return false;
 
148
        }
 
149
 
 
150
        p = 0;
 
151
        while (!f.eos()) {
 
152
                _palettes[p].end = f.readUint16LE();
 
153
                _palettes[p].cnt = f.readUint16LE();
 
154
 
 
155
                for (i = 0; i < _palettes[p].cnt; i++) {
 
156
                        _palettes[p].pal[4 * i] = f.readByte();
 
157
                        _palettes[p].pal[4 * i + 1] = f.readByte();
 
158
                        _palettes[p].pal[4 * i + 2] = f.readByte();
 
159
                        _palettes[p].pal[4 * i + 3] = 0;
 
160
                }
 
161
                for (; i < 256; i++) {
 
162
                        _palettes[p].pal[4 * i] = 0;
 
163
                        _palettes[p].pal[4 * i + 1] = 0;
 
164
                        _palettes[p].pal[4 * i + 2] = 0;
 
165
                        _palettes[p].pal[4 * i + 3] = 0;
 
166
                }
 
167
 
 
168
                p++;
 
169
        }
 
170
 
 
171
        f.close();
 
172
 
 
173
        _palNum = 0;
 
174
        _maxPalNum = p;
 
175
        setPalette(_palettes[_palNum].pal);
 
176
        _lut = _lut2 = _yuvLookup[0];
 
177
        _curPal = -1;
 
178
        _cr = 0;
 
179
        buildLookup(_palNum, 256);
 
180
        _lut2 = _yuvLookup[1];
 
181
        _lutCalcNum = (BITDEPTH + _palettes[_palNum].end + 2) / (_palettes[_palNum].end + 2);
 
182
#else
 
183
        buildLookup();
 
184
        _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
 
185
        _sys->showOverlay();
 
186
#endif
 
187
 
 
188
        // Open MPEG2 stream
 
189
        _mpegFile = new Common::File();
 
190
        sprintf(tempFile, "%s.mp2", name);
 
191
        if (!_mpegFile->open(tempFile)) {
 
192
                warning("Cutscene: Could not open %s", tempFile);
 
193
                return false;
 
194
        }
 
195
 
 
196
        // Load and configure decoder
 
197
        _mpegDecoder = mpeg2_init();
 
198
        if (_mpegDecoder == NULL) {
 
199
                warning("Cutscene: Could not allocate an MPEG2 decoder");
 
200
                return false;
 
201
        }
 
202
 
 
203
        _mpegInfo = mpeg2_info(_mpegDecoder);
 
204
        _frameNum = 0;
 
205
 
 
206
        return true;
 
207
#else /* USE_MPEG2 */
 
208
        return false;
 
209
#endif
 
210
}
 
211
 
 
212
bool BaseAnimationState::decodeFrame() {
 
213
#ifdef USE_MPEG2
 
214
        mpeg2_state_t state;
 
215
        const mpeg2_sequence_t *sequence_i;
 
216
        size_t size = (size_t) -1;
 
217
        static byte buf[BUFFER_SIZE];
 
218
 
 
219
        do {
 
220
                state = mpeg2_parse(_mpegDecoder);
 
221
                sequence_i = _mpegInfo->sequence;
 
222
 
 
223
                switch (state) {
 
224
                case STATE_BUFFER:
 
225
                        size = _mpegFile->read(buf, BUFFER_SIZE);
 
226
                        mpeg2_buffer(_mpegDecoder, buf, buf + size);
 
227
                        break;
 
228
 
 
229
                case STATE_SLICE:
 
230
                case STATE_END:
 
231
                        if (_mpegInfo->display_fbuf) {
 
232
                                checkPaletteSwitch();
 
233
                                drawYUV(sequence_i->width, sequence_i->height, _mpegInfo->display_fbuf->buf);
 
234
#ifdef BACKEND_8BIT
 
235
                                buildLookup(_palNum + 1, _lutCalcNum);
 
236
#endif
 
237
 
 
238
                                _frameNum++;
 
239
                                return true;
 
240
                        }
 
241
                        break;
 
242
 
 
243
                default:
 
244
                        break;
 
245
                }
 
246
        } while (size);
 
247
#endif
 
248
        return false;
 
249
}
 
250
 
 
251
bool BaseAnimationState::checkPaletteSwitch() {
 
252
#ifdef BACKEND_8BIT
 
253
        // if we have reached the last image with this palette, switch to new one
 
254
        if (_frameNum == _palettes[_palNum].end) {
 
255
                unsigned char *l = _lut2;
 
256
                _palNum++;
 
257
                setPalette(_palettes[_palNum].pal);
 
258
                _lutCalcNum = (BITDEPTH + _palettes[_palNum].end - (_frameNum + 1) + 2) / (_palettes[_palNum].end - (_frameNum + 1) + 2);
 
259
                _lut2 = _lut;
 
260
                _lut = l;
 
261
                return true;
 
262
        }
 
263
#endif
 
264
 
 
265
        return false;
 
266
}
 
267
 
 
268
void BaseAnimationState::handleScreenChanged() {
 
269
#ifndef BACKEND_8BIT
 
270
        const int screenW = _sys->getOverlayWidth();
 
271
        const int screenH = _sys->getOverlayHeight();
 
272
 
 
273
        int newScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
 
274
 
 
275
        assert(newScale >= 1);
 
276
        if (newScale > 3)
 
277
                newScale = 3;
 
278
 
 
279
        if (newScale != _movieScale) {
 
280
                // HACK: Since frames generally do not cover the entire screen,
 
281
                //       We need to undraw the old frame. This is a very hacky
 
282
                //       way of doing that.
 
283
                OverlayColor *buf = (OverlayColor *)calloc(screenW * screenH, sizeof(OverlayColor));
 
284
                _sys->copyRectToOverlay(buf, screenW, 0, 0, screenW, screenH);
 
285
                free(buf);
 
286
 
 
287
                free(_overlay);
 
288
                _movieScale = newScale;
 
289
                _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
 
290
        }
 
291
 
 
292
        buildLookup();
 
293
#endif
 
294
}
 
295
 
 
296
#ifdef BACKEND_8BIT
 
297
 
 
298
/**
 
299
 * Build 'Best-Match' RGB lookup table
 
300
 */
 
301
void BaseAnimationState::buildLookup(int p, int lines) {
 
302
        int y, cb;
 
303
        int r, g, b, ii;
 
304
 
 
305
        if (p >= _maxPalNum)
 
306
                return;
 
307
 
 
308
        if (p != _curPal) {
 
309
                _curPal = p;
 
310
                _cr = 0;
 
311
                _pos = 0;
 
312
        }
 
313
 
 
314
        if (_cr > BITDEPTH)
 
315
                return;
 
316
 
 
317
        for (ii = 0; ii < lines; ii++) {
 
318
                r = (-16 * 256 + (int) (256 * 1.596) * ((_cr << SHIFT) - 128)) / 256;
 
319
                for (cb = 0; cb <= BITDEPTH; cb++) {
 
320
                        g = (-16 * 256 - (int) (0.813 * 256) * ((_cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
 
321
                        b = (-16 * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
 
322
 
 
323
                        for (y = 0; y <= BITDEPTH; y++) {
 
324
                                int idx, bst = 0;
 
325
                                int dis = 2 * SQR(r - _palettes[p].pal[0]) + 4 * SQR(g - _palettes[p].pal[1]) + SQR(b - _palettes[p].pal[2]);
 
326
 
 
327
                                for (idx = 1; idx < 256; idx++) {
 
328
                                        long d2 = 2 * SQR(r - _palettes[p].pal[4 * idx]) + 4 * SQR(g - _palettes[p].pal[4 * idx + 1]) + SQR(b - _palettes[p].pal[4 * idx + 2]);
 
329
                                        if (d2 < dis) {
 
330
                                                bst = idx;
 
331
                                                dis = d2;
 
332
                                        }
 
333
                                }
 
334
                                _lut2[_pos++] = bst;
 
335
 
 
336
                                r += (1 << SHIFT);
 
337
                                g += (1 << SHIFT);
 
338
                                b += (1 << SHIFT);
 
339
                        }
 
340
                        r -= (BITDEPTH + 1) * (1 << SHIFT);
 
341
                }
 
342
                _cr++;
 
343
                if (_cr > BITDEPTH)
 
344
                        return;
 
345
        }
 
346
}
 
347
 
 
348
#else
 
349
 
 
350
void BaseAnimationState::buildLookup() {
 
351
        // Do we already have lookup tables for this bit format?
 
352
        Graphics::PixelFormat format = _sys->getOverlayFormat();
 
353
        if (format == _overlayFormat && _colorTab && _rgbToPix)
 
354
                return;
 
355
 
 
356
        free(_colorTab);
 
357
        free(_rgbToPix);
 
358
 
 
359
        _colorTab = (int16 *)malloc(4 * 256 * sizeof(int16));
 
360
 
 
361
        int16 *Cr_r_tab = &_colorTab[0 * 256];
 
362
        int16 *Cr_g_tab = &_colorTab[1 * 256];
 
363
        int16 *Cb_g_tab = &_colorTab[2 * 256];
 
364
        int16 *Cb_b_tab = &_colorTab[3 * 256];
 
365
 
 
366
        _rgbToPix = (OverlayColor *)malloc(3 * 768 * sizeof(OverlayColor));
 
367
 
 
368
        OverlayColor *r_2_pix_alloc = &_rgbToPix[0 * 768];
 
369
        OverlayColor *g_2_pix_alloc = &_rgbToPix[1 * 768];
 
370
        OverlayColor *b_2_pix_alloc = &_rgbToPix[2 * 768];
 
371
 
 
372
        int16 CR, CB;
 
373
        int i;
 
374
 
 
375
        // Generate the tables for the display surface
 
376
 
 
377
        for (i = 0; i < 256; i++) {
 
378
                // Gamma correction (luminescence table) and chroma correction
 
379
                // would be done here. See the Berkeley mpeg_play sources.
 
380
 
 
381
                CR = CB = (i - 128);
 
382
                Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
 
383
                Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
 
384
                Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
 
385
                Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
 
386
        }
 
387
 
 
388
        // Set up entries 0-255 in rgb-to-pixel value tables.
 
389
        for (i = 0; i < 256; i++) {
 
390
                r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0);
 
391
                g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0);
 
392
                b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i);
 
393
        }
 
394
 
 
395
        // Spread out the values we have to the rest of the array so that we do
 
396
        // not need to check for overflow.
 
397
        for (i = 0; i < 256; i++) {
 
398
                r_2_pix_alloc[i] = r_2_pix_alloc[256];
 
399
                r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
 
400
                g_2_pix_alloc[i] = g_2_pix_alloc[256];
 
401
                g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
 
402
                b_2_pix_alloc[i] = b_2_pix_alloc[256];
 
403
                b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
 
404
        }
 
405
 
 
406
        _overlayFormat = format;
 
407
}
 
408
 
 
409
void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) {
 
410
        switch (_movieScale) {
 
411
        case 1:
 
412
                plotYUV1x(width, height, dat);
 
413
                break;
 
414
        case 2:
 
415
                plotYUV2x(width, height, dat);
 
416
                break;
 
417
        case 3:
 
418
                plotYUV3x(width, height, dat);
 
419
                break;
 
420
        }
 
421
}
 
422
 
 
423
void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) {
 
424
        byte *lum = dat[0];
 
425
        byte *cr = dat[2];
 
426
        byte *cb = dat[1];
 
427
 
 
428
        byte *lum2 = lum + width;
 
429
 
 
430
        int16 cr_r;
 
431
        int16 crb_g;
 
432
        int16 cb_b;
 
433
 
 
434
        OverlayColor *row1 = _overlay;
 
435
        OverlayColor *row2 = row1 + _movieWidth;
 
436
 
 
437
        int x;
 
438
 
 
439
        for (; height > 0; height -= 2) {
 
440
                OverlayColor *r1 = row1;
 
441
                OverlayColor *r2 = row2;
 
442
 
 
443
                for (x = width; x > 0; x -= 2) {
 
444
                        register OverlayColor *L;
 
445
 
 
446
                        cr_r  = _colorTab[*cr + 0 * 256];
 
447
                        crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
 
448
                        cb_b  = _colorTab[*cb + 3 * 256];
 
449
                        ++cr;
 
450
                        ++cb;
 
451
 
 
452
                        L = &_rgbToPix[*lum++];
 
453
                        *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
 
454
 
 
455
                        L = &_rgbToPix[*lum++];
 
456
                        *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
 
457
 
 
458
                        // Now, do second row.
 
459
 
 
460
                        L = &_rgbToPix[*lum2++];
 
461
                        *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
 
462
 
 
463
                        L = &_rgbToPix[*lum2++];
 
464
                        *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
 
465
                }
 
466
 
 
467
                lum  += width;
 
468
                lum2 += width;
 
469
                row1 += 2 * _movieWidth;
 
470
                row2 += 2 * _movieWidth;
 
471
        }
 
472
}
 
473
 
 
474
void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) {
 
475
        byte *lum = dat[0];
 
476
        byte *cr = dat[2];
 
477
        byte *cb = dat[1];
 
478
 
 
479
        byte *lum2 = lum + width;
 
480
 
 
481
        int16 cr_r;
 
482
        int16 crb_g;
 
483
        int16 cb_b;
 
484
 
 
485
        OverlayColor *row1 = _overlay;
 
486
        OverlayColor *row2 = row1 + 2 * 2 * _movieWidth;
 
487
 
 
488
        int x;
 
489
 
 
490
        for (; height > 0; height -= 2) {
 
491
                OverlayColor *r1 = row1;
 
492
                OverlayColor *r2 = row2;
 
493
 
 
494
                for (x = width; x > 0; x -= 2) {
 
495
                        register OverlayColor *L;
 
496
                        register OverlayColor  C;
 
497
 
 
498
                        cr_r  = _colorTab[*cr + 0 * 256];
 
499
                        crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
 
500
                        cb_b  = _colorTab[*cb + 3 * 256];
 
501
                        ++cr;
 
502
                        ++cb;
 
503
 
 
504
                        L = &_rgbToPix[*lum++];
 
505
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
506
                        *r1++ = C;
 
507
                        *r1++ = C;
 
508
 
 
509
                        L = &_rgbToPix[*lum++];
 
510
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
511
                        *r1++ = C;
 
512
                        *r1++ = C;
 
513
 
 
514
                        // Now, do second row.
 
515
 
 
516
                        L = &_rgbToPix[*lum2++];
 
517
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
518
                        *r2++ = C;
 
519
                        *r2++ = C;
 
520
 
 
521
                        L = &_rgbToPix[*lum2++];
 
522
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
523
                        *r2++ = C;
 
524
                        *r2++ = C;
 
525
                }
 
526
 
 
527
                memcpy(row1 + 2 * _movieWidth, row1, 2 * _movieWidth * sizeof(OverlayColor));
 
528
                memcpy(row2 + 2 * _movieWidth, row2, 2 * _movieWidth * sizeof(OverlayColor));
 
529
 
 
530
                lum  += width;
 
531
                lum2 += width;
 
532
                row1 += 4 * 2 * _movieWidth;
 
533
                row2 += 4 * 2 * _movieWidth;
 
534
        }
 
535
}
 
536
 
 
537
void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) {
 
538
        byte *lum = dat[0];
 
539
        byte *cr = dat[2];
 
540
        byte *cb = dat[1];
 
541
 
 
542
        byte *lum2 = lum + width;
 
543
 
 
544
        int16 cr_r;
 
545
        int16 crb_g;
 
546
        int16 cb_b;
 
547
 
 
548
        OverlayColor *row1 = _overlay;
 
549
        OverlayColor *row2 = row1 + 3 * 3 * _movieWidth;
 
550
 
 
551
        int x;
 
552
 
 
553
        for (; height > 0; height -= 2) {
 
554
                OverlayColor *r1 = row1;
 
555
                OverlayColor *r2 = row2;
 
556
 
 
557
                for (x = width; x > 0; x -= 2) {
 
558
                        register OverlayColor *L;
 
559
                        register OverlayColor  C;
 
560
 
 
561
                        cr_r  = _colorTab[*cr + 0 * 256];
 
562
                        crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
 
563
                        cb_b  = _colorTab[*cb + 3 * 256];
 
564
                        ++cr;
 
565
                        ++cb;
 
566
 
 
567
                        L = &_rgbToPix[*lum++];
 
568
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
569
                        *r1++ = C;
 
570
                        *r1++ = C;
 
571
                        *r1++ = C;
 
572
 
 
573
                        L = &_rgbToPix[*lum++];
 
574
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
575
                        *r1++ = C;
 
576
                        *r1++ = C;
 
577
                        *r1++ = C;
 
578
 
 
579
                        // Now, do second row.
 
580
 
 
581
                        L = &_rgbToPix[*lum2++];
 
582
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
583
                        *r2++ = C;
 
584
                        *r2++ = C;
 
585
                        *r2++ = C;
 
586
 
 
587
                        L = &_rgbToPix[*lum2++];
 
588
                        C = L[cr_r] | L[crb_g] | L[cb_b];
 
589
                        *r2++ = C;
 
590
                        *r2++ = C;
 
591
                        *r2++ = C;
 
592
                }
 
593
 
 
594
                memcpy(row1 + 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
 
595
                memcpy(row1 + 2 * 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
 
596
                memcpy(row2 + 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
 
597
                memcpy(row2 + 2 * 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
 
598
 
 
599
                lum  += width;
 
600
                lum2 += width;
 
601
                row1 += 6 * 3 * _movieWidth;
 
602
                row2 += 6 * 3 * _movieWidth;
 
603
        }
 
604
}
 
605
 
 
606
#endif
 
607
 
 
608
void BaseAnimationState::updateScreen() {
 
609
#ifndef BACKEND_8BIT
 
610
        int width = _movieScale * _frameWidth;
 
611
        int height = _movieScale * _frameHeight;
 
612
        int pitch = _movieScale * _movieWidth;
 
613
 
 
614
        const int screenW = _sys->getOverlayWidth();
 
615
        const int screenH = _sys->getOverlayHeight();
 
616
 
 
617
        int x = (screenW - _movieScale * _frameWidth) / 2;
 
618
        int y = (screenH - _movieScale * _frameHeight) / 2;
 
619
 
 
620
        _sys->copyRectToOverlay(_overlay, pitch, x, y, width, height);
 
621
#endif
 
622
        _sys->updateScreen();
 
623
}
 
624
 
 
625
} // End of namespace Video