diff options
author | Torbjörn Andersson | 2004-03-24 07:29:59 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2004-03-24 07:29:59 +0000 |
commit | afefe7dcfa7bc3a360b77ecd67c3650b426438d5 (patch) | |
tree | da04c0b2e2305029a14ebef5b7901fe8c77b558e | |
parent | 1f1c929cae5883335030d8a112989cc8d38fb246 (diff) | |
download | scummvm-rg350-afefe7dcfa7bc3a360b77ecd67c3650b426438d5.tar.gz scummvm-rg350-afefe7dcfa7bc3a360b77ecd67c3650b426438d5.tar.bz2 scummvm-rg350-afefe7dcfa7bc3a360b77ecd67c3650b426438d5.zip |
Use the binary .pal file format that was introduced for 0.6.0.
Invalidate the lookup table when the screen changes. (TODO: We also have to
invalidate it if the change happens between cutscenes, don't we?)
Some cleanup, particularly in the BS2 cutscene player. More needed, I
guess...
svn-id: r13377
-rw-r--r-- | graphics/animation.cpp | 51 | ||||
-rw-r--r-- | graphics/animation.h | 3 | ||||
-rw-r--r-- | sword1/animation.cpp | 24 | ||||
-rw-r--r-- | sword2/driver/animation.cpp | 97 | ||||
-rw-r--r-- | sword2/driver/animation.h | 5 | ||||
-rw-r--r-- | sword2/driver/d_draw.h | 2 |
6 files changed, 111 insertions, 71 deletions
diff --git a/graphics/animation.cpp b/graphics/animation.cpp index 63bf92f42d..79a0aad0d2 100644 --- a/graphics/animation.cpp +++ b/graphics/animation.cpp @@ -61,33 +61,27 @@ bool BaseAnimationState::init(const char *name) { uint i, p; // Load lookup palettes - // TODO: Binary format so we can use File class sprintf(tempFile, "%s.pal", name); - FILE *f = fopen(tempFile, "r"); - if (!f) { - warning("Cutscene: %s.pal palette missing", name); + File f; + + if (!f.open(tempFile)) { + warning("Cutscene: %s palette missing", tempFile); return false; } p = 0; - while (!feof(f)) { - int end, cnt; + while (1) { + palettes[p].end = f.readUint16LE(); + palettes[p].cnt = f.readUint16LE(); - if (fscanf(f, "%i %i", &end, &cnt) != 2) + if (f.ioFailed()) break; - palettes[p].end = (uint) end; - palettes[p].cnt = (uint) cnt; - for (i = 0; i < palettes[p].cnt; i++) { - int r, g, b; - fscanf(f, "%i", &r); - fscanf(f, "%i", &g); - fscanf(f, "%i", &b); - palettes[p].pal[4 * i] = r; - palettes[p].pal[4 * i + 1] = g; - palettes[p].pal[4 * i + 2] = b; + palettes[p].pal[4 * i] = f.readByte(); + palettes[p].pal[4 * i + 1] = f.readByte(); + palettes[p].pal[4 * i + 2] = f.readByte(); palettes[p].pal[4 * i + 3] = 0; } for (; i < 256; i++) { @@ -96,9 +90,11 @@ bool BaseAnimationState::init(const char *name) { palettes[p].pal[4 * i + 2] = 0; palettes[p].pal[4 * i + 3] = 0; } + p++; } - fclose(f); + + f.close(); palnum = 0; maxPalnum = p; @@ -300,6 +296,25 @@ void BaseAnimationState::buildLookup(int p, int lines) { OverlayColor *BaseAnimationState::lookup = 0; +/** + * This function should be called when the screen changes to invalidate and, + * optionally, rebuild the lookup table. + * @param rebuild If true, rebuild the table. + */ + +// FIXME: We will need to call the function from the game's main event loop +// as well, not just the cutscene players' ones. + +// FIXME: It would be nice with a heuristic to check if the table really does +// need to be rebuilt. + +void BaseAnimationState::invalidateLookup(bool rebuild) { + free(lookup); + lookup = 0; + if (rebuild) + buildLookup(); +} + void BaseAnimationState::buildLookup() { if (lookup) return; diff --git a/graphics/animation.h b/graphics/animation.h index e4a92a66fa..044bfbd069 100644 --- a/graphics/animation.h +++ b/graphics/animation.h @@ -124,6 +124,9 @@ public: bool init(const char *name); bool decodeFrame(); +#ifndef BACKEND_8BIT + void invalidateLookup(bool rebuild); +#endif protected: bool checkPaletteSwitch(); diff --git a/sword1/animation.cpp b/sword1/animation.cpp index 0b79d91a07..fa1c91bf45 100644 --- a/sword1/animation.cpp +++ b/sword1/animation.cpp @@ -69,16 +69,26 @@ void MoviePlayer::play(const char *filename) { #ifndef BACKEND_8BIT _sys->updateScreen(); #endif - // FIXME: check for ESC and abbort animation be just returning from the function OSystem::Event event; while (_sys->poll_event(&event)) { - if ((event.event_code == OSystem::EVENT_KEYDOWN) && - (event.kbd.keycode == 27)) { - delete anim; - return; - } - if (event.event_code == OSystem::EVENT_QUIT) + switch (event.event_code) { +#ifndef BACKEND_8BIT + case OSystem::EVENT_SCREEN_CHANGED: + anim->invalidateLookup(true); + break; +#endif + case OSystem::EVENT_KEYDOWN: + if (event.kbd.keycode == 27) { + delete anim; + return; + } + break; + case OSystem::EVENT_QUIT: _sys->quit(); + break; + default: + break; + } } } } diff --git a/sword2/driver/animation.cpp b/sword2/driver/animation.cpp index 0f6436727f..8c952a90b5 100644 --- a/sword2/driver/animation.cpp +++ b/sword2/driver/animation.cpp @@ -76,29 +76,33 @@ void AnimationState::drawTextObject(SpriteInfo *s, uint8 *src) { } } -void AnimationState::clearDisplay(void) { +#endif + +void AnimationState::clearScreen(void) { +#ifdef BACKEND_8BIT + memset(_vm->_graphics->getScreen(), 0, MOVIE_WIDTH * MOVIE_HEIGHT); +#else OverlayColor black = _sys->RGBToColor(0, 0, 0); for (int i = 0; i < MOVIE_WIDTH * MOVIE_HEIGHT; i++) overlay[i] = black; +#endif } -void AnimationState::updateDisplay(void) { - _sys->copy_rect_overlay(overlay, MOVIE_WIDTH, 0, 0, MOVIE_WIDTH, MOVIE_HEIGHT); -} +void AnimationState::updateScreen(void) { +#ifdef BACKEND_8BIT + byte *buf = _vm->_graphics->getScreen() + ((480 - MOVIE_HEIGHT) / 2) * RENDERWIDE + (640 - MOVIE_WIDTH) / 2; + _vm->_system->copy_rect(buf, MOVIE_WIDTH, (640 - MOVIE_WIDTH) / 2, (480 - MOVIE_HEIGHT) / 2, MOVIE_WIDTH, MOVIE_HEIGHT); +#else + _sys->copy_rect_overlay(overlay, MOVIE_WIDTH, 0, 0, MOVIE_WIDTH, MOVIE_HEIGHT); #endif + _vm->_system->updateScreen(); +} void AnimationState::drawYUV(int width, int height, byte *const *dat) { #ifdef BACKEND_8BIT _vm->_graphics->plotYUV(lut, width, height, dat); - // FIXME: We used to call setNeedFullRedraw() a bit later (that is, - // it was called by decodeFrame(), after the 'delay_msecs' calls, so - // after the syncing code. Not sure if moving it here causes any - // problems, and I have no way to test it. However I do not see why - // it should cause problems... of course that doesn't mean anything, - // only that I can't see that far :-) - _vm->_graphics->setNeedFullRedraw(); #else plotYUV(lookup, width, height, dat); #endif @@ -163,6 +167,10 @@ void MoviePlayer::drawTextObject(AnimationState *anim, MovieTextObject *obj) { */ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *musicOut) { + // This happens if the user quits during the "eye" smacker + if (_vm->_quit) + return RD_OK; + #ifdef USE_MPEG2 uint frameCounter = 0, textCounter = 0; PlayingSoundHandle handle; @@ -182,7 +190,8 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu return RD_OK; } - _vm->_graphics->clearScene(); + anim->clearScreen(); + anim->updateScreen(); #ifndef SCUMM_BIG_ENDIAN flags |= SoundMixer::FLAG_LITTLE_ENDIAN; @@ -204,7 +213,10 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu if (i == ARRAYSIZE(_movies)) warning("Unknown movie, '%s'", filename); - while (anim->decodeFrame()) { + while (!skipCutscene && anim->decodeFrame()) { + // The frame has been drawn. Now draw the subtitles, if any, + // before updating the screen. + if (text && text[textCounter]) { if (frameCounter == text[textCounter]->startFrame) { openTextObject(text[textCounter]); @@ -225,30 +237,38 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu textCounter++; textVisible = false; } + if (textVisible) drawTextObject(anim, text[textCounter]); } + anim->updateScreen(); + frameCounter++; if (frameCounter == leadOutFrame && musicOut) _vm->_sound->playFx(0, musicOut, 0, 0, RDSE_FXLEADOUT); -#ifdef BACKEND_8BIT - _vm->_graphics->updateDisplay(true); -#else - anim->updateDisplay(); - _vm->_graphics->updateDisplay(false); + OSystem::Event event; + while (_sys->poll_event(&event)) { + switch (event.event_code) { +#ifndef BACKEND_8BIT + case OSystem::EVENT_SCREEN_CHANGED: + anim->invalidateLookup(true); + break; #endif - - KeyboardEvent ke; - - if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) { - _snd->stopHandle(handle); - skipCutscene = true; - break; + case OSystem::EVENT_KEYDOWN: + if (event.kbd.keycode == 27) + skipCutscene = true; + break; + case OSystem::EVENT_QUIT: + _vm->closeGame(); + skipCutscene = true; + break; + default: + break; + } } - } if (!skipCutscene) { @@ -256,16 +276,11 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu _sys->delay_msecs(1000 / 12); } -#ifndef BACKEND_8BIT // Most movies fade to black on their own, but not all of them. Since // we may be hanging around in the cutscene player for a while longer, // waiting for the lead-out sound to finish, paint the overlay black. - anim->clearDisplay(); -#else - _vm->_graphics->clearScene(); - _vm->_graphics->setNeedFullRedraw(); -#endif + anim->clearScreen(); // If the speech is still playing, redraw the subtitles. At least in // the English version this is most noticeable in the "carib" cutscene. @@ -276,17 +291,16 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu if (text) closeTextObject(text[textCounter]); -#ifndef BACKEND_8BIT - anim->updateDisplay(); -#else - _vm->_graphics->updateDisplay(true); -#endif + anim->updateScreen(); // Wait for the voice to stop playing. This is to make sure // that we don't cut off the speech in mid-sentence, and - even // more importantly - that we don't free the sound buffer while // it's in use. + if (skipCutscene) + _snd->stopHandle(handle); + while (handle.isActive()) { _vm->_graphics->updateDisplay(false); _sys->delay_msecs(100); @@ -294,13 +308,8 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu // Clear the screen again -#ifndef BACKEND_8BIT - anim->clearDisplay(); - anim->updateDisplay(); -#endif - - _vm->_graphics->clearScene(); - _vm->_graphics->setNeedFullRedraw(); + anim->clearScreen(); + anim->updateScreen(); _vm->_graphics->setPalette(0, 256, oldPal, RDPAL_INSTANT); diff --git a/sword2/driver/animation.h b/sword2/driver/animation.h index 00fea9fa67..818167537e 100644 --- a/sword2/driver/animation.h +++ b/sword2/driver/animation.h @@ -39,10 +39,11 @@ public: #ifndef BACKEND_8BIT void drawTextObject(SpriteInfo *s, uint8 *src); - void clearDisplay(); - void updateDisplay(void); #endif + void clearScreen(); + void updateScreen(void); + private: void drawYUV(int width, int height, byte *const *dat); diff --git a/sword2/driver/d_draw.h b/sword2/driver/d_draw.h index c40bc0e0af..257be0d117 100644 --- a/sword2/driver/d_draw.h +++ b/sword2/driver/d_draw.h @@ -182,6 +182,8 @@ public: uint8 _palCopy[256][4]; + byte *getScreen(void) { return _buffer; } + int8 getRenderLevel(void); void setRenderLevel(int8 level); |