[Scummvm-devel] Re: CVS: scummvm/sword2/driver animation.cpp,1.2,1.3 animation.h,1.4,1.5 d_draw.cpp,1.58,1.59 d_draw.h,1.23,1.24
James 'Ender' Brown
ender at scummvm.org
Tue Jan 13 04:04:01 CET 2004
Kirben encounted this problem too. Do files you encode yourself work,
such as for SCUMM engine games?
As this is a simple call to the existing mixer OGG engine, I could only
say that either the oggenc I used is creating oddly broken files or that
something else is wrong.
- Ender
On Tue, 2004-01-13 at 18:09, Torbj?rn Andersson wrote:
> Update of /cvsroot/scummvm/scummvm/sword2/driver
> In directory sc8-pr-cvs1:/tmp/cvs-serv27656
>
> Modified Files:
> animation.cpp animation.h d_draw.cpp d_draw.h
> Log Message:
> Moved the rest of the MoviePlayer class into animation.cpp/.h, plus some
> minor cleanups. (Mostly spacing and indentation).
>
> Unfortunately the Ogg Vorbis playback causes ScummVM to crash for me, so I
> can't say for certain that I didn't break anything.
>
>
> Index: animation.cpp
> ===================================================================
> RCS file: /cvsroot/scummvm/scummvm/sword2/driver/animation.cpp,v
> retrieving revision 1.2
> retrieving revision 1.3
> diff -u -d -r1.2 -r1.3
> --- animation.cpp 13 Jan 2004 01:26:18 -0000 1.2
> +++ animation.cpp 13 Jan 2004 10:09:53 -0000 1.3
> @@ -28,11 +28,13 @@
>
> namespace Sword2 {
>
> -// Build 'Best-Match' RGB lookup table
> +/**
> + * Build 'Best-Match' RGB lookup table
> + */
> +
> void AnimationState::buildLookup(int p, int lines) {
> int y, cb;
> int r, g, b, ii;
> -
>
> if (p != curpal) {
> curpal = p;
> @@ -44,17 +46,17 @@
> return;
>
> for (ii = 0; ii < lines; ii++) {
> - r = (-16*256 + (int)(256*1.596) * ((cr<<SHIFT)-128)) / 256;
> + r = (-16 * 256 + (int) (256 * 1.596) * ((cr << SHIFT) - 128)) / 256;
> for (cb = 0; cb < BITDEPTH; cb++) {
> - g = (-16*256 - (int)(0.813*256) * ((cr<<SHIFT)-128) - (int)(0.391*256) * ((cb<<SHIFT)-128)) / 256;
> - b = (-16*256 + (int)(2.018*256) * ((cb<<SHIFT)-128)) / 256;
> + g = (-16 * 256 - (int) (0.813 * 256) * ((cr << SHIFT) - 128) - (int) (0.391 * 256) * ((cb << SHIFT) - 128)) / 256;
> + b = (-16 * 256 + (int) (2.018 * 256) * ((cb << SHIFT) - 128)) / 256;
>
> for (y = 0; y < BITDEPTH; y++) {
> int idx, bst = 0;
> - int dis = 2*SQR(r-palettes[p].pal[0])+4*SQR(g-palettes[p].pal[1])+SQR(b-palettes[p].pal[2]);
> + int dis = 2 * SQR(r - palettes[p].pal[0]) + 4 * SQR(g - palettes[p].pal[1]) + SQR(b - palettes[p].pal[2]);
>
> for (idx = 1; idx < 256; idx++) {
> - 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]);
> + 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]);
> if (d2 < dis) {
> bst = idx;
> dis = d2;
> @@ -74,6 +76,294 @@
> }
> }
>
> +void MoviePlayer::openTextObject(MovieTextObject *obj) {
> + if (obj->textSprite)
> + _vm->_graphics->createSurface(obj->textSprite, &_textSurface);
> +}
> +
> +void MoviePlayer::closeTextObject(MovieTextObject *obj) {
> + if (_textSurface) {
> + _vm->_graphics->deleteSurface(_textSurface);
> + _textSurface = NULL;
> + }
> +}
> +
> +void MoviePlayer::drawTextObject(MovieTextObject *obj) {
> + if (obj->textSprite && _textSurface)
> + _vm->_graphics->drawSurface(obj->textSprite, _textSurface);
> +}
> +
> +/**
> + * Plays an animated cutscene.
> + * @param filename the file name of the cutscene file
> + * @param text the subtitles and voiceovers for the cutscene
> + * @param musicOut lead-out music
> + */
> +
> +int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *musicOut) {
> +#ifdef USE_MPEG2
> + int frameCounter = 0, textCounter = 0;
> + PlayingSoundHandle handle;
> + bool skipCutscene = false, textVisible = false;
> + uint32 flags = SoundMixer::FLAG_16BITS, ticks = _vm->_system->get_msecs() + 83;
> +
> + uint8 oldPal[1024];
> + memcpy(oldPal, _vm->_graphics->_palCopy, 1024);
> +
> + AnimationState * anim = initAnimation(filename);
> + if (!anim) {
> + // Missing Files? Use the old 'Narration Only' hack
> + playDummy(filename, text, musicOut);
> + return RD_OK;
> + }
> +
> + _vm->_graphics->clearScene();
> + memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> +
> +#ifndef SCUMM_BIG_ENDIAN
> + flags |= SoundMixer::FLAG_LITTLE_ENDIAN;
> +#endif
> +
> + while (1) {
> + if (!decodeFrame(anim)) break;
> + _vm->_graphics->setNeedFullRedraw();
> +
> + if (text && text[textCounter]) {
> + if (frameCounter == text[textCounter]->startFrame) {
> + openTextObject(text[textCounter]);
> + textVisible = true;
> + if (text[textCounter]->speech) {
> + _vm->_mixer->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
> + }
> + }
> +
> + if (frameCounter == text[textCounter]->endFrame) {
> + closeTextObject(text[textCounter]);
> + textCounter++;
> + textVisible = false;
> + }
> + if (textVisible)
> + drawTextObject(text[textCounter]);
> + }
> +
> + frameCounter++;
> +
> + _vm->_graphics->updateDisplay(true);
> +
> + KeyboardEvent ke;
> +
> + if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) {
> + _vm->_mixer->stopHandle(handle);
> + skipCutscene = true;
> + break;
> + }
> +
> + // Simulate ~12 frames per second. I don't know what
> + // frame rate the original movies had, or even if it
> + // was constant, but this seems to work reasonably.
> +
> + _vm->sleepUntil(ticks);
> + ticks += 82;
> +
> + }
> +
> + // 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.
> +
> + while (handle.isActive()) {
> + _vm->_graphics->updateDisplay(false);
> + _vm->_system->delay_msecs(100);
> + }
> +
> + if (text)
> + closeTextObject(text[textCounter]);
> +
> + _vm->_graphics->clearScene();
> + _vm->_graphics->setNeedFullRedraw();
> +
> + // HACK: Remove the instructions created above
> + Common::Rect r;
> +
> + memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> + r.left = r.top = 0;
> + r.right = _vm->_graphics->_screenWide;
> + r.bottom = MENUDEEP;
> + _vm->_graphics->updateRect(&r);
> +
> + // FIXME: For now, only play the lead-out music for cutscenes
> + // that have subtitles.
> + if (!skipCutscene)
> + _vm->_sound->playLeadOut(musicOut);
> +
> + _vm->_graphics->setPalette(0, 256, oldPal, RDPAL_INSTANT);
> +
> + doneAnimation(anim);
> +
> + // Lead-in and lead-out music are, as far as I can tell, only used for
> + // the animated cut-scenes, so this seems like a good place to close
> + // both of them.
> +
> + _vm->_sound->closeFx(-1);
> + _vm->_sound->closeFx(-2);
> +
> + return RD_OK;
> +#else
> + // No MPEG2? Use the old 'Narration Only' hack
> + playDummy(filename, text, musicOut);
> + return RD_OK;
> +#endif
> +}
> +
> +/**
> + * This just plays the cutscene with voiceovers / subtitles, in case the files
> + * are missing.
> + */
> +
> +int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut) {
> + int frameCounter = 0, textCounter = 0;
> + if (text) {
> + uint8 oldPal[1024];
> + uint8 tmpPal[1024];
> +
> + _vm->_graphics->clearScene();
> +
> + // HACK: Draw instructions
> + //
> + // I'm using the the menu area, because that's unlikely to be
> + // touched by anything else during the cutscene.
> +
> + memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> +
> + uint8 msg[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos";
> + Memory *data = _vm->_fontRenderer->makeTextSprite(msg, 640, 255, _vm->_speechFontId);
> + FrameHeader *frame = (FrameHeader *) data->ad;
> + SpriteInfo msgSprite;
> + uint8 *msgSurface;
> +
> + msgSprite.x = _vm->_graphics->_screenWide / 2 - frame->width / 2;
> + msgSprite.y = RDMENU_MENUDEEP / 2 - frame->height / 2;
> + msgSprite.w = frame->width;
> + msgSprite.h = frame->height;
> + msgSprite.type = RDSPR_NOCOMPRESSION;
> + msgSprite.data = data->ad + sizeof(FrameHeader);
> +
> + _vm->_graphics->createSurface(&msgSprite, &msgSurface);
> + _vm->_graphics->drawSurface(&msgSprite, msgSurface);
> + _vm->_graphics->deleteSurface(msgSurface);
> + _vm->_memory->freeMemory(data);
> +
> + // In case the cutscene has a long lead-in, start just before
> + // the first line of text.
> +
> + frameCounter = text[0]->startFrame - 12;
> +
> + // Fake a palette that will hopefully make the text visible.
> + // In the opening cutscene it seems to use colours 1 (black?)
> + // and 255 (white?).
> + //
> + // The text should probably be colored the same as the rest of
> + // the in-game text.
> +
> + memcpy(oldPal, _vm->_graphics->_palCopy, 1024);
> + memset(tmpPal, 0, 1024);
> + tmpPal[255 * 4 + 0] = 255;
> + tmpPal[255 * 4 + 1] = 255;
> + tmpPal[255 * 4 + 2] = 255;
> + _vm->_graphics->setPalette(0, 256, tmpPal, RDPAL_INSTANT);
> +
> + PlayingSoundHandle handle;
> +
> + bool skipCutscene = false;
> +
> + uint32 flags = SoundMixer::FLAG_16BITS;
> +
> +#ifndef SCUMM_BIG_ENDIAN
> + flags |= SoundMixer::FLAG_LITTLE_ENDIAN;
> +#endif
> +
> + while (1) {
> + if (!text[textCounter])
> + break;
> +
> + if (frameCounter == text[textCounter]->startFrame) {
> + _vm->_graphics->clearScene();
> + openTextObject(text[textCounter]);
> + drawTextObject(text[textCounter]);
> + if (text[textCounter]->speech) {
> + _vm->_mixer->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
> + }
> + }
> + if (frameCounter == text[textCounter]->endFrame) {
> + closeTextObject(text[textCounter]);
> + _vm->_graphics->clearScene();
> + _vm->_graphics->setNeedFullRedraw();
> + textCounter++;
> + }
> +
> + frameCounter++;
> +
> + _vm->_graphics->updateDisplay();
> +
> + KeyboardEvent ke;
> +
> + if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) {
> + _vm->_mixer->stopHandle(handle);
> + skipCutscene = true;
> + break;
> + }
> +
> + // Simulate ~12 frames per second. I don't know what
> + // frame rate the original movies had, or even if it
> + // was constant, but this seems to work reasonably.
> +
> + _vm->_system->delay_msecs(90);
> + }
> +
> + // 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.
> +
> + while (handle.isActive()) {
> + _vm->_graphics->updateDisplay(false);
> + _vm->_system->delay_msecs(100);
> + }
> +
> + closeTextObject(text[textCounter]);
> +
> + _vm->_graphics->clearScene();
> + _vm->_graphics->setNeedFullRedraw();
> +
> + // HACK: Remove the instructions created above
> + Common::Rect r;
> +
> + memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> + r.left = r.top = 0;
> + r.right = _vm->_graphics->_screenWide;
> + r.bottom = MENUDEEP;
> + _vm->_graphics->updateRect(&r);
> +
> + // FIXME: For now, only play the lead-out music for cutscenes
> + // that have subtitles.
> +
> + if (!skipCutscene)
> + _vm->_sound->playLeadOut(musicOut);
> +
> + _vm->_graphics->setPalette(0, 256, oldPal, RDPAL_INSTANT);
> + }
> +
> + // Lead-in and lead-out music are, as far as I can tell, only used for
> + // the animated cut-scenes, so this seems like a good place to close
> + // both of them.
> +
> + _vm->_sound->closeFx(-1);
> + _vm->_sound->closeFx(-2);
> +
> + return RD_OK;
> +}
> +
> void MoviePlayer::checkPaletteSwitch(AnimationState * st) {
> // if we have reached the last image with this palette, switch to new one
> if (st->framenum == st->palettes[st->palnum].end) {
> @@ -86,52 +376,42 @@
> }
> }
>
> -#ifndef USE_MPEG2
> -bool MoviePlayer::decodeFrame(AnimationState * st) {
> - // Dummy for MPEG2-less builds
> - return false;
> -}
> -#else
> +#ifdef USE_MPEG2
> +
> bool MoviePlayer::decodeFrame(AnimationState * st) {
> mpeg2_state_t state;
> const mpeg2_sequence_t *sequence_i;
> - size_t size = (size_t)-1;
> + size_t size = (size_t) -1;
>
> do {
> - state = mpeg2_parse (st->decoder);
> + state = mpeg2_parse(st->decoder);
> sequence_i = st->info->sequence;
>
> switch (state) {
> - case STATE_BUFFER:
> - size = st->mpgfile->read(st->buffer, BUFFER_SIZE);
> - mpeg2_buffer (st->decoder, st->buffer, st->buffer + size);
> + case STATE_BUFFER:
> + size = st->mpgfile->read(st->buffer, BUFFER_SIZE);
> + mpeg2_buffer(st->decoder, st->buffer, st->buffer + size);
> break;
>
> - case STATE_SLICE:
> - case STATE_END:
> - if (st->info->display_fbuf) {
> - checkPaletteSwitch(st);
> - _vm->_graphics->plotYUV(st->lut, sequence_i->width, sequence_i->height, st->info->display_fbuf->buf);
> - st->framenum++;
> - st->buildLookup(st->palnum+1, st->lutcalcnum);
> - return true;
> - }
> + case STATE_SLICE:
> + case STATE_END:
> + if (st->info->display_fbuf) {
> + checkPaletteSwitch(st);
> + _vm->_graphics->plotYUV(st->lut, sequence_i->width, sequence_i->height, st->info->display_fbuf->buf);
> + st->framenum++;
> + st->buildLookup(st->palnum + 1, st->lutcalcnum);
> + return true;
> + }
> break;
>
> - default:
> - break;
> + default:
> + break;
> }
> } while (size);
>
> return false;
> }
> -#endif
>
> -#ifndef USE_MPEG2
> -AnimationState *MoviePlayer::initAnimation(const char *name) {
> - return 0;
> -}
> -#else
> AnimationState *MoviePlayer::initAnimation(const char *name) {
> char basename[512], tempFile[512];
> AnimationState *st = new AnimationState;
> @@ -158,9 +438,9 @@
> fscanf(f, "%i", &r);
> fscanf(f, "%i", &g);
> fscanf(f, "%i", &b);
> - st->palettes[p].pal[4*i] = r;
> - st->palettes[p].pal[4*i+1] = g;
> - st->palettes[p].pal[4*i+2] = b;
> + st->palettes[p].pal[4 * i] = r;
> + st->palettes[p].pal[4 * i + 1] = g;
> + st->palettes[p].pal[4 * i + 2] = b;
> }
> p++;
> }
> @@ -184,7 +464,7 @@
> }
>
> // Load and configure decoder
> - st->decoder = mpeg2_init ();
> + st->decoder = mpeg2_init();
> if (st->decoder == NULL) {
> warning("Cutscene: Could not allocate an MPEG2 decoder");
> delete st;
> @@ -195,34 +475,48 @@
> st->framenum = 0;
>
> // Load in palette data
> - st->lutcalcnum = (BITDEPTH + st->palettes[st->palnum].end + 2) / (st->palettes[st->palnum].end + 2);
> -
> + st->lutcalcnum = (BITDEPTH + st->palettes[st->palnum].end + 2) / (st->palettes[st->palnum].end + 2);
>
> /* Play audio - TODO: Sync with video?*/
> +
> +#ifdef USE_VORBIS
> // Another TODO: There is no reason that this only allows OGG, and not MP3, or any other format
> // the mixer might support one day... is there?
> File *sndFile = new File;
> sprintf(tempFile, "%s.ogg", basename);
> if (sndFile->open(tempFile))
> _vm->_mixer->playVorbis(&st->bgSound, sndFile, 100000000);
> +#endif
>
> // FIXME: This leaks (sndFile will never be deleted)
>
> return st;
> }
> -#endif
>
> -#ifndef USE_MPEG2
> -void MoviePlayer::doneAnimation(AnimationState *st) {
> -}
> -#else
> void MoviePlayer::doneAnimation(AnimationState *st) {
> - _vm->_mixer->stopHandle(st->bgSound);
> + if (st->bgSound.isActive())
> + _vm->_mixer->stopHandle(st->bgSound);
>
> mpeg2_close (st->decoder);
> st->mpgfile->close();
> delete st->mpgfile;
> delete st;
> }
> +
> +#else
> +
> +bool MoviePlayer::decodeFrame(AnimationState * st) {
> + // Dummy for MPEG2-less builds
> + return false;
> +}
> +
> +AnimationState *MoviePlayer::initAnimation(const char *name) {
> + return 0;
> +}
> +
> +void MoviePlayer::doneAnimation(AnimationState *st) {
> +}
> +
> #endif
> +
> } // End of namespace Sword2
>
> Index: animation.h
> ===================================================================
> RCS file: /cvsroot/scummvm/scummvm/sword2/driver/animation.h,v
> retrieving revision 1.4
> retrieving revision 1.5
> diff -u -d -r1.4 -r1.5
> --- animation.h 13 Jan 2004 01:26:18 -0000 1.4
> +++ animation.h 13 Jan 2004 10:09:53 -0000 1.5
> @@ -41,41 +41,61 @@
>
> #define BUFFER_SIZE 4096
>
> -
> class AnimationState {
> public:
> - int palnum;
> + int palnum;
>
> - byte lookup[2][BITDEPTH * BITDEPTH * BITDEPTH];
> - byte *lut;
> - byte *lut2;
> - int lutcalcnum;
> + byte lookup[2][BITDEPTH * BITDEPTH * BITDEPTH];
> + byte *lut;
> + byte *lut2;
> + int lutcalcnum;
>
> - int framenum;
> + int framenum;
>
> - #ifdef USE_MPEG2
> - mpeg2dec_t *decoder;
> - const mpeg2_info_t *info;
> - #endif
> - File *mpgfile;
> +#ifdef USE_MPEG2
> + mpeg2dec_t *decoder;
> + const mpeg2_info_t *info;
> +#endif
>
> - int curpal;
> - int cr;
> - int pos;
> + File *mpgfile;
>
> - struct {
> - int cnt;
> - int end;
> - byte pal[4 * 256];
> - } palettes[50];
> + int curpal;
> + int cr;
> + int pos;
>
> - byte buffer[BUFFER_SIZE];
> + struct {
> + int cnt;
> + int end;
> + byte pal[4 * 256];
> + } palettes[50];
>
> - PlayingSoundHandle bgSound;
> + byte buffer[BUFFER_SIZE];
> +
> + PlayingSoundHandle bgSound;
>
> public:
> void buildLookup(int p, int lines);
> +};
> +
> +class MoviePlayer {
> +private:
> + Sword2Engine *_vm;
> + uint8 *_textSurface;
> +
> + void openTextObject(MovieTextObject *obj);
> + void closeTextObject(MovieTextObject *obj);
> + void drawTextObject(MovieTextObject *obj);
> +
> + void checkPaletteSwitch(AnimationState * st);
>
> + AnimationState * initAnimation(const char *name);
> + void doneAnimation(AnimationState * st);
> + bool decodeFrame(AnimationState * st);
> +
> +public:
> + MoviePlayer(Sword2Engine *vm) : _vm(vm), _textSurface(NULL) {}
> + int32 play(const char *filename, MovieTextObject *text[], uint8 *musicOut);
> + int32 playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut);
> };
>
> } // End of namespace Sword2
>
> Index: d_draw.cpp
> ===================================================================
> RCS file: /cvsroot/scummvm/scummvm/sword2/driver/d_draw.cpp,v
> retrieving revision 1.58
> retrieving revision 1.59
> diff -u -d -r1.58 -r1.59
> --- d_draw.cpp 13 Jan 2004 01:26:18 -0000 1.58
> +++ d_draw.cpp 13 Jan 2004 10:09:53 -0000 1.59
> @@ -116,289 +116,4 @@
> memset(_buffer + MENUDEEP * _screenWide, 0, _screenWide * RENDERDEEP);
> }
>
> -void MoviePlayer::openTextObject(MovieTextObject *obj) {
> - if (obj->textSprite)
> - _vm->_graphics->createSurface(obj->textSprite, &_textSurface);
> -}
> -
> -void MoviePlayer::closeTextObject(MovieTextObject *obj) {
> - if (_textSurface) {
> - _vm->_graphics->deleteSurface(_textSurface);
> - _textSurface = NULL;
> - }
> -}
> -
> -void MoviePlayer::drawTextObject(MovieTextObject *obj) {
> - if (obj->textSprite && _textSurface)
> - _vm->_graphics->drawSurface(obj->textSprite, _textSurface);
> -}
> -
> -/**
> - * Plays an animated cutscene.
> - * @param filename the file name of the cutscene file
> - * @param text the subtitles and voiceovers for the cutscene
> - * @param musicOut lead-out music
> - */
> -
> -int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *musicOut) {
> -#ifdef USE_MPEG2
> - int frameCounter = 0, textCounter = 0;
> - PlayingSoundHandle handle;
> - bool skipCutscene = false, textVisible = false;
> - uint32 flags = SoundMixer::FLAG_16BITS, ticks = _vm->_system->get_msecs() + 83;
> -
> - uint8 oldPal[1024];
> - memcpy(oldPal, _vm->_graphics->_palCopy, 1024);
> -
> - AnimationState * anim = initAnimation(filename);
> - if (!anim) {
> - // Missing Files? Use the old 'Narration Only' hack
> - playDummy(filename, text, musicOut);
> - return RD_OK;
> - }
> -
> - _vm->_graphics->clearScene();
> - memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> -
> -
> -#ifndef SCUMM_BIG_ENDIAN
> - flags |= SoundMixer::FLAG_LITTLE_ENDIAN;
> -#endif
> -
> - while (1) {
> - if (!decodeFrame(anim)) break;
> - _vm->_graphics->setNeedFullRedraw();
> -
> - if (text && text[textCounter]) {
> - if (frameCounter == text[textCounter]->startFrame) {
> - openTextObject(text[textCounter]);
> - textVisible = true;
> - if (text[textCounter]->speech) {
> - _vm->_mixer->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
> - }
> - }
> -
> - if (frameCounter == text[textCounter]->endFrame) {
> - closeTextObject(text[textCounter]);
> - textCounter++;
> - textVisible = false;
> - }
> - if (textVisible)
> - drawTextObject(text[textCounter]);
> - }
> -
> - frameCounter++;
> -
> - _vm->_graphics->updateDisplay(true);
> -
> - KeyboardEvent ke;
> -
> - if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) {
> - _vm->_mixer->stopHandle(handle);
> - skipCutscene = true;
> - break;
> - }
> -
> - // Simulate ~12 frames per second. I don't know what
> - // frame rate the original movies had, or even if it
> - // was constant, but this seems to work reasonably.
> -
> - _vm->sleepUntil(ticks);
> - ticks += 82;
> -
> - }
> -
> - // 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.
> -
> - while (handle.isActive()) {
> - _vm->_graphics->updateDisplay(false);
> - _vm->_system->delay_msecs(100);
> - }
> -
> - if (text)
> - closeTextObject(text[textCounter]);
> -
> - _vm->_graphics->clearScene();
> - _vm->_graphics->setNeedFullRedraw();
> -
> - // HACK: Remove the instructions created above
> - Common::Rect r;
> -
> - memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> - r.left = r.top = 0;
> - r.right = _vm->_graphics->_screenWide;
> - r.bottom = MENUDEEP;
> - _vm->_graphics->updateRect(&r);
> -
> - // FIXME: For now, only play the lead-out music for cutscenes
> - // that have subtitles.
> - if (!skipCutscene)
> - _vm->_sound->playLeadOut(musicOut);
> -
> - _vm->_graphics->setPalette(0, 256, oldPal, RDPAL_INSTANT);
> -
> - doneAnimation(anim);
> -
> - // Lead-in and lead-out music are, as far as I can tell, only used for
> - // the animated cut-scenes, so this seems like a good place to close
> - // both of them.
> -
> - _vm->_sound->closeFx(-1);
> - _vm->_sound->closeFx(-2);
> -
> - return RD_OK;
> -#else
> - // No MPEG2? Use the old 'Narration Only' hack
> - playDummy(filename, text, musicOut);
> - return RD_OK;
> -#endif
> -}
> -
> -// This just plays the cutscene with voiceovers / subtitles, in case the files are missing
> -int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut) {
> - int frameCounter = 0, textCounter = 0;
> - if (text) {
> - uint8 oldPal[1024];
> - uint8 tmpPal[1024];
> -
> - _vm->_graphics->clearScene();
> -
> - // HACK: Draw instructions
> - //
> - // I'm using the the menu area, because that's unlikely to be
> - // touched by anything else during the cutscene.
> -
> - memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> -
> - uint8 msg[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos";
> - Memory *data = _vm->_fontRenderer->makeTextSprite(msg, 640, 255, _vm->_speechFontId);
> - FrameHeader *frame = (FrameHeader *) data->ad;
> - SpriteInfo msgSprite;
> - uint8 *msgSurface;
> -
> - msgSprite.x = _vm->_graphics->_screenWide / 2 - frame->width / 2;
> - msgSprite.y = RDMENU_MENUDEEP / 2 - frame->height / 2;
> - msgSprite.w = frame->width;
> - msgSprite.h = frame->height;
> - msgSprite.type = RDSPR_NOCOMPRESSION;
> - msgSprite.data = data->ad + sizeof(FrameHeader);
> -
> - _vm->_graphics->createSurface(&msgSprite, &msgSurface);
> - _vm->_graphics->drawSurface(&msgSprite, msgSurface);
> - _vm->_graphics->deleteSurface(msgSurface);
> - _vm->_memory->freeMemory(data);
> -
> - // In case the cutscene has a long lead-in, start just before
> - // the first line of text.
> -
> - frameCounter = text[0]->startFrame - 12;
> -
> - // Fake a palette that will hopefully make the text visible.
> - // In the opening cutscene it seems to use colours 1 (black?)
> - // and 255 (white?).
> - //
> - // The text should probably be colored the same as the rest of
> - // the in-game text.
> -
> - memcpy(oldPal, _vm->_graphics->_palCopy, 1024);
> - memset(tmpPal, 0, 1024);
> - tmpPal[255 * 4 + 0] = 255;
> - tmpPal[255 * 4 + 1] = 255;
> - tmpPal[255 * 4 + 2] = 255;
> - _vm->_graphics->setPalette(0, 256, tmpPal, RDPAL_INSTANT);
> -
> - PlayingSoundHandle handle;
> -
> - bool skipCutscene = false;
> -
> - uint32 flags = SoundMixer::FLAG_16BITS;
> -
> -#ifndef SCUMM_BIG_ENDIAN
> - flags |= SoundMixer::FLAG_LITTLE_ENDIAN;
> -#endif
> -
> - while (1) {
> - if (!text[textCounter])
> - break;
> -
> - if (frameCounter == text[textCounter]->startFrame) {
> - _vm->_graphics->clearScene();
> - openTextObject(text[textCounter]);
> - drawTextObject(text[textCounter]);
> - if (text[textCounter]->speech) {
> - _vm->_mixer->playRaw(&handle, text[textCounter]->speech, text[textCounter]->speechBufferSize, 22050, flags);
> - }
> - }
> - if (frameCounter == text[textCounter]->endFrame) {
> - closeTextObject(text[textCounter]);
> - _vm->_graphics->clearScene();
> - _vm->_graphics->setNeedFullRedraw();
> - textCounter++;
> - }
> -
> - frameCounter++;
> -
> - _vm->_graphics->updateDisplay();
> -
> - KeyboardEvent ke;
> -
> - if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) {
> - _vm->_mixer->stopHandle(handle);
> - skipCutscene = true;
> - break;
> - }
> -
> - // Simulate ~12 frames per second. I don't know what
> - // frame rate the original movies had, or even if it
> - // was constant, but this seems to work reasonably.
> -
> - _vm->_system->delay_msecs(90);
> - }
> -
> - // 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.
> -
> - while (handle.isActive()) {
> - _vm->_graphics->updateDisplay(false);
> - _vm->_system->delay_msecs(100);
> - }
> -
> - closeTextObject(text[textCounter]);
> -
> - _vm->_graphics->clearScene();
> - _vm->_graphics->setNeedFullRedraw();
> -
> - // HACK: Remove the instructions created above
> - Common::Rect r;
> -
> - memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP);
> - r.left = r.top = 0;
> - r.right = _vm->_graphics->_screenWide;
> - r.bottom = MENUDEEP;
> - _vm->_graphics->updateRect(&r);
> -
> - // FIXME: For now, only play the lead-out music for cutscenes
> - // that have subtitles.
> -
> - if (!skipCutscene)
> - _vm->_sound->playLeadOut(musicOut);
> -
> - _vm->_graphics->setPalette(0, 256, oldPal, RDPAL_INSTANT);
> - }
> -
> - // Lead-in and lead-out music are, as far as I can tell, only used for
> - // the animated cut-scenes, so this seems like a good place to close
> - // both of them.
> -
> - _vm->_sound->closeFx(-1);
> - _vm->_sound->closeFx(-2);
> -
> - return RD_OK;
> -}
> -
> } // End of namespace Sword2
>
> Index: d_draw.h
> ===================================================================
> RCS file: /cvsroot/scummvm/scummvm/sword2/driver/d_draw.h,v
> retrieving revision 1.23
> retrieving revision 1.24
> diff -u -d -r1.23 -r1.24
> --- d_draw.h 13 Jan 2004 01:26:18 -0000 1.23
> +++ d_draw.h 13 Jan 2004 10:09:53 -0000 1.24
> @@ -65,27 +65,6 @@
> #pragma END_PACK_STRUCTS
> #endif
>
> -class MoviePlayer {
> -private:
> - Sword2Engine *_vm;
> - uint8 *_textSurface;
> -
> - void openTextObject(MovieTextObject *obj);
> - void closeTextObject(MovieTextObject *obj);
> - void drawTextObject(MovieTextObject *obj);
> -
> - void checkPaletteSwitch(AnimationState * st);
> -
> - AnimationState * initAnimation(const char *name);
> - void doneAnimation(AnimationState * st);
> - bool decodeFrame(AnimationState * st);
> -
> -public:
> - MoviePlayer(Sword2Engine *vm) : _vm(vm), _textSurface(NULL) {}
> - int32 play(const char *filename, MovieTextObject *text[], uint8 *musicOut);
> - int32 playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut);
> -};
> -
> struct BlockSurface {
> byte data[BLOCKWIDTH * BLOCKHEIGHT];
> bool transparent;
>
More information about the Scummvm-devel
mailing list