Speech bubbles can point down right.
[scummvm-innocent.git] / graphics / video / mpeg_player.cpp
blob5b7b3eb607f1a3834c425cbed3cfe0b74a871899
1 /* ScummVM - Graphic Adventure Engine
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.
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.
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.
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.
21 * $URL$
22 * $Id$
26 #include "graphics/video/mpeg_player.h"
27 #include "common/file.h"
28 #include "common/system.h"
29 #include "common/util.h"
30 #include "graphics/scaler/intern.h"
32 namespace Graphics {
34 BaseAnimationState::BaseAnimationState(OSystem *sys, int width, int height)
35 : _movieWidth(width), _movieHeight(height), _frameWidth(width), _frameHeight(height), _sys(sys) {
36 #ifndef BACKEND_8BIT
37 const int screenW = _sys->getOverlayWidth();
38 const int screenH = _sys->getOverlayHeight();
40 _movieScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
42 assert(_movieScale >= 1);
43 if (_movieScale > 3)
44 _movieScale = 3;
46 _colorTab = NULL;
47 _rgbToPix = NULL;
48 memset(&_overlayFormat, 0, sizeof(_overlayFormat));
49 #endif
52 BaseAnimationState::~BaseAnimationState() {
53 #ifdef USE_MPEG2
54 if (_mpegDecoder)
55 mpeg2_close(_mpegDecoder);
56 delete _mpegFile;
57 #ifndef BACKEND_8BIT
58 _sys->hideOverlay();
59 free(_overlay);
60 free(_colorTab);
61 free(_rgbToPix);
62 #endif
63 #endif
67 bool BaseAnimationState::init(const char *name) {
68 #ifdef USE_MPEG2
69 char tempFile[512];
71 _mpegDecoder = NULL;
72 _mpegFile = NULL;
74 #ifdef BACKEND_8BIT
76 uint i, p;
78 // Load lookup palettes
79 sprintf(tempFile, "%s.pal", name);
81 Common::File f;
83 if (!f.open(tempFile)) {
84 warning("Cutscene: %s palette missing", tempFile);
85 return false;
88 p = 0;
89 while (!f.eos()) {
90 _palettes[p].end = f.readUint16LE();
91 _palettes[p].cnt = f.readUint16LE();
93 for (i = 0; i < _palettes[p].cnt; i++) {
94 _palettes[p].pal[4 * i] = f.readByte();
95 _palettes[p].pal[4 * i + 1] = f.readByte();
96 _palettes[p].pal[4 * i + 2] = f.readByte();
97 _palettes[p].pal[4 * i + 3] = 0;
99 for (; i < 256; i++) {
100 _palettes[p].pal[4 * i] = 0;
101 _palettes[p].pal[4 * i + 1] = 0;
102 _palettes[p].pal[4 * i + 2] = 0;
103 _palettes[p].pal[4 * i + 3] = 0;
106 p++;
109 f.close();
111 _palNum = 0;
112 _maxPalNum = p;
113 setPalette(_palettes[_palNum].pal);
114 _lut = _lut2 = _yuvLookup[0];
115 _curPal = -1;
116 _cr = 0;
117 buildLookup(_palNum, 256);
118 _lut2 = _yuvLookup[1];
119 _lutCalcNum = (BITDEPTH + _palettes[_palNum].end + 2) / (_palettes[_palNum].end + 2);
120 #else
121 buildLookup();
122 _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
123 _sys->showOverlay();
124 #endif
126 // Open MPEG2 stream
127 _mpegFile = new Common::File();
128 sprintf(tempFile, "%s.mp2", name);
129 if (!_mpegFile->open(tempFile)) {
130 warning("Cutscene: Could not open %s", tempFile);
131 return false;
134 // Load and configure decoder
135 _mpegDecoder = mpeg2_init();
136 if (_mpegDecoder == NULL) {
137 warning("Cutscene: Could not allocate an MPEG2 decoder");
138 return false;
141 _mpegInfo = mpeg2_info(_mpegDecoder);
142 _frameNum = 0;
144 return true;
145 #else /* USE_MPEG2 */
146 return false;
147 #endif
150 bool BaseAnimationState::decodeFrame() {
151 #ifdef USE_MPEG2
152 mpeg2_state_t state;
153 const mpeg2_sequence_t *sequence_i;
154 size_t size = (size_t) -1;
155 static byte buf[BUFFER_SIZE];
157 do {
158 state = mpeg2_parse(_mpegDecoder);
159 sequence_i = _mpegInfo->sequence;
161 switch (state) {
162 case STATE_BUFFER:
163 size = _mpegFile->read(buf, BUFFER_SIZE);
164 mpeg2_buffer(_mpegDecoder, buf, buf + size);
165 break;
167 case STATE_SLICE:
168 case STATE_END:
169 if (_mpegInfo->display_fbuf) {
170 checkPaletteSwitch();
171 drawYUV(sequence_i->width, sequence_i->height, _mpegInfo->display_fbuf->buf);
172 #ifdef BACKEND_8BIT
173 buildLookup(_palNum + 1, _lutCalcNum);
174 #endif
176 _frameNum++;
177 return true;
179 break;
181 default:
182 break;
184 } while (size);
185 #endif
186 return false;
189 bool BaseAnimationState::checkPaletteSwitch() {
190 #ifdef BACKEND_8BIT
191 // if we have reached the last image with this palette, switch to new one
192 if (_frameNum == _palettes[_palNum].end) {
193 unsigned char *l = _lut2;
194 _palNum++;
195 setPalette(_palettes[_palNum].pal);
196 _lutCalcNum = (BITDEPTH + _palettes[_palNum].end - (_frameNum + 1) + 2) / (_palettes[_palNum].end - (_frameNum + 1) + 2);
197 _lut2 = _lut;
198 _lut = l;
199 return true;
201 #endif
203 return false;
206 void BaseAnimationState::handleScreenChanged() {
207 #ifndef BACKEND_8BIT
208 const int screenW = _sys->getOverlayWidth();
209 const int screenH = _sys->getOverlayHeight();
211 int newScale = MIN(screenW / _movieWidth, screenH / _movieHeight);
213 assert(newScale >= 1);
214 if (newScale > 3)
215 newScale = 3;
217 if (newScale != _movieScale) {
218 // HACK: Since frames generally do not cover the entire screen,
219 // We need to undraw the old frame. This is a very hacky
220 // way of doing that.
221 OverlayColor *buf = (OverlayColor *)calloc(screenW * screenH, sizeof(OverlayColor));
222 _sys->copyRectToOverlay(buf, screenW, 0, 0, screenW, screenH);
223 free(buf);
225 free(_overlay);
226 _movieScale = newScale;
227 _overlay = (OverlayColor *)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor));
230 buildLookup();
231 #endif
234 #ifdef BACKEND_8BIT
237 * Build 'Best-Match' RGB lookup table
239 void BaseAnimationState::buildLookup(int p, int lines) {
240 int y, cb;
241 int r, g, b, ii;
243 if (p >= _maxPalNum)
244 return;
246 if (p != _curPal) {
247 _curPal = p;
248 _cr = 0;
249 _pos = 0;
252 if (_cr > BITDEPTH)
253 return;
255 for (ii = 0; ii < lines; ii++) {
256 r = (-16 * 256 + (int) (256 * 1.596) * ((_cr << SHIFT) - 128)) / 256;
257 for (cb = 0; cb <= BITDEPTH; cb++) {
258 g = (-16 * 256 - (int) (0.813 * 256) * ((_cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
259 b = (-16 * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
261 for (y = 0; y <= BITDEPTH; y++) {
262 int idx, bst = 0;
263 int dis = 2 * SQR(r - _palettes[p].pal[0]) + 4 * SQR(g - _palettes[p].pal[1]) + SQR(b - _palettes[p].pal[2]);
265 for (idx = 1; idx < 256; idx++) {
266 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]);
267 if (d2 < dis) {
268 bst = idx;
269 dis = d2;
272 _lut2[_pos++] = bst;
274 r += (1 << SHIFT);
275 g += (1 << SHIFT);
276 b += (1 << SHIFT);
278 r -= (BITDEPTH + 1) * (1 << SHIFT);
280 _cr++;
281 if (_cr > BITDEPTH)
282 return;
286 #else
288 // The YUV to RGB conversion code is derived from SDL's YUV overlay code, which
289 // in turn appears to be derived from mpeg_play. The following copyright
290 // notices have been included in accordance with the original license. Please
291 // note that the term "software" in this context only applies to the two
292 // functions buildLookup() and plotYUV() below.
294 // Copyright (c) 1995 The Regents of the University of California.
295 // All rights reserved.
297 // Permission to use, copy, modify, and distribute this software and its
298 // documentation for any purpose, without fee, and without written agreement is
299 // hereby granted, provided that the above copyright notice and the following
300 // two paragraphs appear in all copies of this software.
302 // IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
303 // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
304 // OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
305 // CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
307 // THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
308 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
309 // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
310 // ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
311 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
313 // Copyright (c) 1995 Erik Corry
314 // All rights reserved.
316 // Permission to use, copy, modify, and distribute this software and its
317 // documentation for any purpose, without fee, and without written agreement is
318 // hereby granted, provided that the above copyright notice and the following
319 // two paragraphs appear in all copies of this software.
321 // IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
322 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
323 // THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
324 // OF THE POSSIBILITY OF SUCH DAMAGE.
326 // ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
327 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
328 // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
329 // BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
330 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
332 // Portions of this software Copyright (c) 1995 Brown University.
333 // All rights reserved.
335 // Permission to use, copy, modify, and distribute this software and its
336 // documentation for any purpose, without fee, and without written agreement
337 // is hereby granted, provided that the above copyright notice and the
338 // following two paragraphs appear in all copies of this software.
340 // IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
341 // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
342 // OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
343 // UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
345 // BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
346 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
347 // PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
348 // BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
349 // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
351 void BaseAnimationState::buildLookup() {
352 // Do we already have lookup tables for this bit format?
353 Graphics::PixelFormat format = _sys->getOverlayFormat();
354 if (format == _overlayFormat && _colorTab && _rgbToPix)
355 return;
357 free(_colorTab);
358 free(_rgbToPix);
360 _colorTab = (int16 *)malloc(4 * 256 * sizeof(int16));
362 int16 *Cr_r_tab = &_colorTab[0 * 256];
363 int16 *Cr_g_tab = &_colorTab[1 * 256];
364 int16 *Cb_g_tab = &_colorTab[2 * 256];
365 int16 *Cb_b_tab = &_colorTab[3 * 256];
367 _rgbToPix = (OverlayColor *)malloc(3 * 768 * sizeof(OverlayColor));
369 OverlayColor *r_2_pix_alloc = &_rgbToPix[0 * 768];
370 OverlayColor *g_2_pix_alloc = &_rgbToPix[1 * 768];
371 OverlayColor *b_2_pix_alloc = &_rgbToPix[2 * 768];
373 int16 CR, CB;
374 int i;
376 // Generate the tables for the display surface
378 for (i = 0; i < 256; i++) {
379 // Gamma correction (luminescence table) and chroma correction
380 // would be done here. See the Berkeley mpeg_play sources.
382 CR = CB = (i - 128);
383 Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
384 Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
385 Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
386 Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
389 // Set up entries 0-255 in rgb-to-pixel value tables.
390 for (i = 0; i < 256; i++) {
391 r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0);
392 g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0);
393 b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i);
396 // Spread out the values we have to the rest of the array so that we do
397 // not need to check for overflow.
398 for (i = 0; i < 256; i++) {
399 r_2_pix_alloc[i] = r_2_pix_alloc[256];
400 r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
401 g_2_pix_alloc[i] = g_2_pix_alloc[256];
402 g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
403 b_2_pix_alloc[i] = b_2_pix_alloc[256];
404 b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
407 _overlayFormat = format;
410 void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) {
411 switch (_movieScale) {
412 case 1:
413 plotYUV1x(width, height, dat);
414 break;
415 case 2:
416 plotYUV2x(width, height, dat);
417 break;
418 case 3:
419 plotYUV3x(width, height, dat);
420 break;
424 void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) {
425 byte *lum = dat[0];
426 byte *cr = dat[2];
427 byte *cb = dat[1];
429 byte *lum2 = lum + width;
431 int16 cr_r;
432 int16 crb_g;
433 int16 cb_b;
435 OverlayColor *row1 = _overlay;
436 OverlayColor *row2 = row1 + _movieWidth;
438 int x;
440 for (; height > 0; height -= 2) {
441 OverlayColor *r1 = row1;
442 OverlayColor *r2 = row2;
444 for (x = width; x > 0; x -= 2) {
445 register OverlayColor *L;
447 cr_r = _colorTab[*cr + 0 * 256];
448 crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
449 cb_b = _colorTab[*cb + 3 * 256];
450 ++cr;
451 ++cb;
453 L = &_rgbToPix[*lum++];
454 *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
456 L = &_rgbToPix[*lum++];
457 *r1++ = L[cr_r] | L[crb_g] | L[cb_b];
459 // Now, do second row.
461 L = &_rgbToPix[*lum2++];
462 *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
464 L = &_rgbToPix[*lum2++];
465 *r2++ = L[cr_r] | L[crb_g] | L[cb_b];
468 lum += width;
469 lum2 += width;
470 row1 += 2 * _movieWidth;
471 row2 += 2 * _movieWidth;
475 void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) {
476 byte *lum = dat[0];
477 byte *cr = dat[2];
478 byte *cb = dat[1];
480 byte *lum2 = lum + width;
482 int16 cr_r;
483 int16 crb_g;
484 int16 cb_b;
486 OverlayColor *row1 = _overlay;
487 OverlayColor *row2 = row1 + 2 * 2 * _movieWidth;
489 int x;
491 for (; height > 0; height -= 2) {
492 OverlayColor *r1 = row1;
493 OverlayColor *r2 = row2;
495 for (x = width; x > 0; x -= 2) {
496 register OverlayColor *L;
497 register OverlayColor C;
499 cr_r = _colorTab[*cr + 0 * 256];
500 crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
501 cb_b = _colorTab[*cb + 3 * 256];
502 ++cr;
503 ++cb;
505 L = &_rgbToPix[*lum++];
506 C = L[cr_r] | L[crb_g] | L[cb_b];
507 *r1++ = C;
508 *r1++ = C;
510 L = &_rgbToPix[*lum++];
511 C = L[cr_r] | L[crb_g] | L[cb_b];
512 *r1++ = C;
513 *r1++ = C;
515 // Now, do second row.
517 L = &_rgbToPix[*lum2++];
518 C = L[cr_r] | L[crb_g] | L[cb_b];
519 *r2++ = C;
520 *r2++ = C;
522 L = &_rgbToPix[*lum2++];
523 C = L[cr_r] | L[crb_g] | L[cb_b];
524 *r2++ = C;
525 *r2++ = C;
528 memcpy(row1 + 2 * _movieWidth, row1, 2 * _movieWidth * sizeof(OverlayColor));
529 memcpy(row2 + 2 * _movieWidth, row2, 2 * _movieWidth * sizeof(OverlayColor));
531 lum += width;
532 lum2 += width;
533 row1 += 4 * 2 * _movieWidth;
534 row2 += 4 * 2 * _movieWidth;
538 void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) {
539 byte *lum = dat[0];
540 byte *cr = dat[2];
541 byte *cb = dat[1];
543 byte *lum2 = lum + width;
545 int16 cr_r;
546 int16 crb_g;
547 int16 cb_b;
549 OverlayColor *row1 = _overlay;
550 OverlayColor *row2 = row1 + 3 * 3 * _movieWidth;
552 int x;
554 for (; height > 0; height -= 2) {
555 OverlayColor *r1 = row1;
556 OverlayColor *r2 = row2;
558 for (x = width; x > 0; x -= 2) {
559 register OverlayColor *L;
560 register OverlayColor C;
562 cr_r = _colorTab[*cr + 0 * 256];
563 crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256];
564 cb_b = _colorTab[*cb + 3 * 256];
565 ++cr;
566 ++cb;
568 L = &_rgbToPix[*lum++];
569 C = L[cr_r] | L[crb_g] | L[cb_b];
570 *r1++ = C;
571 *r1++ = C;
572 *r1++ = C;
574 L = &_rgbToPix[*lum++];
575 C = L[cr_r] | L[crb_g] | L[cb_b];
576 *r1++ = C;
577 *r1++ = C;
578 *r1++ = C;
580 // Now, do second row.
582 L = &_rgbToPix[*lum2++];
583 C = L[cr_r] | L[crb_g] | L[cb_b];
584 *r2++ = C;
585 *r2++ = C;
586 *r2++ = C;
588 L = &_rgbToPix[*lum2++];
589 C = L[cr_r] | L[crb_g] | L[cb_b];
590 *r2++ = C;
591 *r2++ = C;
592 *r2++ = C;
595 memcpy(row1 + 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
596 memcpy(row1 + 2 * 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor));
597 memcpy(row2 + 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
598 memcpy(row2 + 2 * 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor));
600 lum += width;
601 lum2 += width;
602 row1 += 6 * 3 * _movieWidth;
603 row2 += 6 * 3 * _movieWidth;
607 #endif
609 void BaseAnimationState::updateScreen() {
610 #ifndef BACKEND_8BIT
611 int width = _movieScale * _frameWidth;
612 int height = _movieScale * _frameHeight;
613 int pitch = _movieScale * _movieWidth;
615 const int screenW = _sys->getOverlayWidth();
616 const int screenH = _sys->getOverlayHeight();
618 int x = (screenW - _movieScale * _frameWidth) / 2;
619 int y = (screenH - _movieScale * _frameHeight) / 2;
621 _sys->copyRectToOverlay(_overlay, pitch, x, y, width, height);
622 #endif
623 _sys->updateScreen();
626 } // End of namespace Graphics