Ticket #8401: animation.diff

File animation.diff, 12.9 KB (added by eriktorbjorn, 19 years ago)

Patch against a March 3 CVS snapshot

  • TODO

    diff -ur --exclude=CVS ScummVM/TODO ScummVM+hack/TODO
    old new  
    9494  some kind of main loop, which, besides many other things, also polls and
    9595  dispatches events. The idea is to turn this around: the event loop
    9696  frequently gives the engine time to do these "other things".
    97 * Try to reduce the memory footprint of the MPEG player. Right now it allocates
    98   an 8 MB lookup table for YUV->RGB conversion. Perhaps we could borrow some
    99   code from SDL's software implementation of YUV overlays. (It might even be
    100   possible to expose some of SDL's YUV overlay API as an optional part of the
    101   backend, but I don't know enough about it to get it to work. We'd still need
    102   our own implementation as a fallback, though.)
    10397* Make the autosave interval configurable (via GUI, command line, config file).
    10498* Maybe add ways to modify the game configs via the command line. E.g. allow
    10599    ./scummvm --add new_target --path=/foo monkey2
  • graphics/animation.cpp

    diff -ur --exclude=CVS ScummVM/graphics/animation.cpp ScummVM+hack/graphics/animation.cpp
    old new  
    2626#include "common/file.h"
    2727#include "common/system.h"
    2828#include "common/util.h"
     29#include "common/scaler/intern.h"
    2930
    3031namespace Graphics {
    3132
    3233BaseAnimationState::BaseAnimationState(SoundMixer *snd, OSystem *sys, int width, int height)
    3334        : MOVIE_WIDTH(width), MOVIE_HEIGHT(height), _snd(snd), _sys(sys) {
     35#ifndef BACKEND_8BIT
     36        colortab = NULL;
     37        rgb_2_pix = NULL;
     38        bitFormat = 0;
     39#endif
    3440}
    3541
    3642BaseAnimationState::~BaseAnimationState() {
     
    4248#ifndef BACKEND_8BIT
    4349        _sys->hideOverlay();
    4450        free(overlay);
     51        free(colortab);
     52        free(rgb_2_pix);
    4553#endif
    4654        delete bgSoundStream;
    4755#endif
     
    297305
    298306#else
    299307
    300 OverlayColor *BaseAnimationState::lookup = 0;
     308// This function, and the next one, are derived from SDL's software YUV overlay
     309// code, which in turn is derived from code carrying the following copyright
     310// notices:
     311
     312// Copyright (c) 1995 The Regents of the University of California.
     313// All rights reserved.
     314//
     315// Permission to use, copy, modify, and distribute this software and its
     316// documentation for any purpose, without fee, and without written agreement is
     317// hereby granted, provided that the above copyright notice and the following
     318// two paragraphs appear in all copies of this software.
     319//
     320// IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
     321// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
     322// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
     323// CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     324//
     325// THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
     326// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     327// AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     328// ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
     329// PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     330
     331// Copyright (c) 1995 Erik Corry
     332// All rights reserved.
     333//
     334// Permission to use, copy, modify, and distribute this software and its
     335// documentation for any purpose, without fee, and without written agreement is
     336// hereby granted, provided that the above copyright notice and the following
     337// two paragraphs appear in all copies of this software.
     338//
     339// IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
     340// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
     341// THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
     342// OF THE POSSIBILITY OF SUCH DAMAGE.
     343//
     344// ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
     345// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     346// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
     347// BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
     348// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     349
     350// Portions of this software Copyright (c) 1995 Brown University.
     351// All rights reserved.
     352//
     353// Permission to use, copy, modify, and distribute this software and its
     354// documentation for any purpose, without fee, and without written agreement
     355// is hereby granted, provided that the above copyright notice and the
     356// following two paragraphs appear in all copies of this software.
     357//
     358// IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
     359// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
     360// OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
     361// UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     362//
     363// BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
     364// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     365// PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
     366// BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
     367// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
    301368
    302 /**
    303  * This function should be called when the screen changes to invalidate and,
    304  * optionally, rebuild the lookup table.
    305  * @param rebuild If true, rebuild the table.
    306  */
     369void BaseAnimationState::buildLookup() {
     370        // Do we already have lookup tables for this bit format?
     371        if (gBitFormat == bitFormat && colortab && rgb_2_pix)
     372                return;
    307373
    308 // FIXME: We will need to call the function from the game's main event loop
    309 // as well, not just the cutscene players' ones.
     374        free(colortab);
     375        free(rgb_2_pix);
    310376
    311 // FIXME: It would be nice with a heuristic to check if the table really does
    312 // need to be rebuilt.
     377        colortab = (int *)malloc(4 * 256 * sizeof(int));
    313378
    314 void BaseAnimationState::invalidateLookup(bool rebuild) {
    315         free(lookup);
    316         lookup = 0;
    317         if (rebuild)
    318                 buildLookup();
    319 }
     379        int *Cr_r_tab = &colortab[0 * 256];
     380        int *Cr_g_tab = &colortab[1 * 256];
     381        int *Cb_g_tab = &colortab[2 * 256];
     382        int *Cb_b_tab = &colortab[3 * 256];
    320383
    321 void BaseAnimationState::buildLookup() {
    322         if (lookup)
    323                 return;
     384        rgb_2_pix = (uint32 *)malloc(3 * 768 * sizeof(uint32));
    324385
    325         lookup = (OverlayColor *)calloc((BITDEPTH+1) * (BITDEPTH+1) * 256, sizeof(OverlayColor));
    326         if (!lookup) {
    327                 warning("Not enough memory to allocate LUT - cannot play sequence");
    328                 return;
    329         }
     386        uint32 *r_2_pix_alloc = &rgb_2_pix[0 * 768];
     387        uint32 *g_2_pix_alloc = &rgb_2_pix[1 * 768];
     388        uint32 *b_2_pix_alloc = &rgb_2_pix[2 * 768];
    330389
    331         int y, cb, cr;
    332         int r, g, b;
    333         int pos = 0;
     390        int CR, CB;
     391        int i;
    334392
    335         for (cr = 0; cr <= BITDEPTH; cr++) {
    336                 for (cb = 0; cb <= BITDEPTH; cb++) {
    337                         for (y = 0; y < 256; y++) {
    338                                 r = ((y - 16) * 256 + (int) (256 * 1.596) * ((cr << SHIFT) - 128)) / 256;
    339                                 g = ((y - 16) * 256 - (int) (0.813 * 256) * ((cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
    340                                 b = ((y - 16) * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
    341 
    342                                 if (r < 0) r = 0;
    343                                 else if (r > 255) r = 255;
    344                                 if (g < 0) g = 0;
    345                                 else if (g > 255) g = 255;
    346                                 if (b < 0) b = 0;
    347                                 else if (b > 255) b = 255;
     393        // Generate the tables for the display surface
    348394
    349                                 lookup[pos++] = _sys->RGBToColor(r, g, b);
    350                         }
     395        for (i = 0; i < 256; i++) {
     396                // Gamma correction (luminescence table) and chroma correction
     397                // would be done here. See the Berkeley mpeg_play sources.
     398
     399                CR = CB = (i - 128);
     400                Cr_r_tab[i] = (int) ( (0.419 / 0.299) * CR);
     401                Cr_g_tab[i] = (int) (-(0.299 / 0.419) * CR);
     402                Cb_g_tab[i] = (int) (-(0.114 / 0.331) * CB);
     403                Cb_b_tab[i] = (int) ( (0.587 / 0.331) * CB);
     404        }
     405
     406        // Set up entries 0-255 in rgb-to-pixel value tables.
     407
     408        if (gBitFormat == 565) {
     409                for (i = 0; i < 256; i++) {
     410                        r_2_pix_alloc[i + 256] = i >> (8 - 5);
     411                        r_2_pix_alloc[i + 256] <<= 11;
     412                        g_2_pix_alloc[i + 256] = i >> (8 - 6);
     413                        g_2_pix_alloc[i + 256] <<= 5;
     414                        b_2_pix_alloc[i + 256] = i >> (8 - 5);
     415                        // b_2_pix_alloc[i + 256] <<= 0;
    351416                }
     417        } else if (gBitFormat == 555) {
     418                for (i = 0; i < 256; i++) {
     419                        r_2_pix_alloc[i + 256] = i >> (8 - 5);
     420                        r_2_pix_alloc[i + 256] <<= 10;
     421                        g_2_pix_alloc[i + 256] = i >> (8 - 5);
     422                        g_2_pix_alloc[i + 256] <<= 5;
     423                        b_2_pix_alloc[i + 256] = i >> (8 - 5);
     424                        // b_2_pix_alloc[i + 256] <<= 0;
     425                }
     426        } else {
     427                error("Unknown bit format %d", gBitFormat);
    352428        }
    353 }
    354429
    355 void BaseAnimationState::plotYUV(OverlayColor *lut, int width, int height, byte *const *dat) {
     430        // Spread out the values we have to the rest of the array so that we do
     431        // not need to check for overflow.
    356432
    357         if (!lut)
    358                 return;
     433        for (i = 0; i < 256; i++) {
     434                r_2_pix_alloc[i] = r_2_pix_alloc[256];
     435                r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
     436                g_2_pix_alloc[i] = g_2_pix_alloc[256];
     437                g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
     438                b_2_pix_alloc[i] = b_2_pix_alloc[256];
     439                b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
     440        }
    359441
     442        bitFormat = gBitFormat;
     443}
     444
     445void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) {
    360446        OverlayColor *ptr = overlay + (MOVIE_HEIGHT - height) / 2 * MOVIE_WIDTH + (MOVIE_WIDTH - width) / 2;
    361447
    362         int x, y;
     448        byte *lum = dat[0];
     449        byte *cr = dat[2];
     450        byte *cb = dat[1];
     451
     452        byte *lum2 = lum + width;
     453
     454        int cr_r;
     455        int crb_g;
     456        int cb_b;
    363457
    364         int ypos = 0;
    365         int cpos = 0;
    366         int linepos = 0;
     458        OverlayColor *row1 = ptr;
     459        OverlayColor *row2 = ptr + MOVIE_WIDTH;
     460
     461        int x, y;
    367462
    368463        for (y = 0; y < height; y += 2) {
    369464                for (x = 0; x < width; x += 2) {
    370                         int i = ((((dat[2][cpos] + ROUNDADD) >> SHIFT) * (BITDEPTH+1)) + ((dat[1][cpos] + ROUNDADD)>>SHIFT)) * 256;
    371                         cpos++;
    372 
    373                         ptr[linepos                ] = lut[i + dat[0][        ypos  ]];
    374                         ptr[MOVIE_WIDTH + linepos++] = lut[i + dat[0][width + ypos++]];
    375                         ptr[linepos                ] = lut[i + dat[0][        ypos  ]];
    376                         ptr[MOVIE_WIDTH + linepos++] = lut[i + dat[0][width + ypos++]];
     465                        register int L;
    377466
     467                        cr_r  = 0 * 768 + 256 + colortab[*cr + 0 * 256];
     468                        crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] + colortab[*cb + 2 * 256];
     469                        cb_b  = 2 * 768 + 256 + colortab[*cb + 3 * 256];
     470                        ++cr;
     471                        ++cb;
     472
     473                        L = *lum++;
     474                        *row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
     475                        L = *lum++;
     476                        *row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
     477
     478                        // Now, do second row.
     479
     480                        L = *lum2++;
     481                        *row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
     482                        L = *lum2++;
     483                        *row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]);
    378484                }
    379                 linepos += (2 * MOVIE_WIDTH - width);
    380                 ypos += width;
     485
     486                // These values are at the start of the next line, (due
     487                // to the ++'s above), but they need to be at the start
     488                // of the line after that.
     489
     490                lum  += width;
     491                lum2 += width;
     492                row1 += (2 * MOVIE_WIDTH - width);
     493                row2 += (2 * MOVIE_WIDTH - width);
    381494        }
    382495}
    383496
  • graphics/animation.h

    diff -ur --exclude=CVS ScummVM/graphics/animation.h ScummVM+hack/graphics/animation.h
    old new  
    109109                byte pal[4 * 256];
    110110        } palettes[50];
    111111#else
    112         static OverlayColor *lookup;
    113112        OverlayColor *overlay;
     113        int bitFormat;
     114        int *colortab;
     115        uint32 *rgb_2_pix;
    114116#endif
    115117
    116118public:
     
    119121
    120122        bool init(const char *name, void *audioArg = NULL);
    121123        bool decodeFrame();
     124
    122125#ifndef BACKEND_8BIT
    123         void invalidateLookup(bool rebuild);
     126        void buildLookup();
    124127#endif
    125128
    126129protected:
     
    132135        void buildLookup(int p, int lines);
    133136        virtual void setPalette(byte *pal) = 0;
    134137#else
    135         void buildLookup(void);
    136         void plotYUV(OverlayColor *lut, int width, int height, byte *const *dat);
     138        void plotYUV(int width, int height, byte *const *dat);
    137139#endif
    138140};
    139141
  • sword1/animation.cpp

    diff -ur --exclude=CVS ScummVM/sword1/animation.cpp ScummVM+hack/sword1/animation.cpp
    old new  
    5050#ifdef BACKEND_8BIT
    5151        _scr->plotYUV(lut, width, height, dat);
    5252#else
    53         plotYUV(lookup, width, height, dat);
     53        plotYUV(width, height, dat);
    5454#endif
    5555}
    5656
     
    145145                                switch (event.type) {
    146146#ifndef BACKEND_8BIT
    147147                                case OSystem::EVENT_SCREEN_CHANGED:
    148                                         anim->invalidateLookup(true);
     148                                        anim->buildLookup();
    149149                                        break;
    150150#endif
    151151                                case OSystem::EVENT_KEYDOWN:
  • sword2/driver/animation.cpp

    diff -ur --exclude=CVS ScummVM/sword2/driver/animation.cpp ScummVM+hack/sword2/driver/animation.cpp
    old new  
    104104#ifdef BACKEND_8BIT
    105105        _vm->_screen->plotYUV(lut, width, height, dat);
    106106#else
    107         plotYUV(lookup, width, height, dat);
     107        plotYUV(width, height, dat);
    108108#endif
    109109}
    110110
     
    308308                        switch (event.type) {
    309309#ifndef BACKEND_8BIT
    310310                        case OSystem::EVENT_SCREEN_CHANGED:
    311                                 anim->invalidateLookup(true);
     311                                anim->buildLookup();
    312312                                break;
    313313#endif
    314314                        case OSystem::EVENT_KEYDOWN: