From 84bb389baedc458e5d10fe230d716e04375ddbf0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 9 Sep 2015 21:02:57 -0400 Subject: SHERLOCK: 3DO: Implement half-size drawing for portrait movies Ideally, it would be great if the portraits could be played at their original size, but it would mean using a higher resolution graphics mode, and changing co-ordinates everywhere in the engine, which would be a major undertaking --- engines/sherlock/scalpel/scalpel.cpp | 23 +++++++++++++++++++++-- engines/sherlock/scalpel/scalpel.h | 2 +- engines/sherlock/scalpel/scalpel_talk.cpp | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index e91c7746c9..90a7493b39 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -1240,8 +1240,9 @@ void ScalpelEngine::showScummVMRestoreDialog() { } } -bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::Point &pos) { +bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::Point &pos, bool halfSize) { Scalpel3DOMovieDecoder *videoDecoder = new Scalpel3DOMovieDecoder(); + Graphics::Surface tempSurface; if (!videoDecoder->loadFile(filename)) { warning("Scalpel3DOMoviePlay: could not open '%s'", filename.c_str()); @@ -1257,12 +1258,30 @@ bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::P _events->clearEvents(); videoDecoder->start(); + // If we're to show the movie at half-size, we'll need a temporary intermediate surface + if (halfSize) + tempSurface.create(width / 2, height / 2, _screen->getPixelFormat()); + while (!shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { if (videoDecoder->needsUpdate()) { const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); if (frame) { - g_system->copyRectToScreen(frame->getPixels(), frame->pitch, pos.x, pos.y, width, height); + if (halfSize) { + // Reduce the movie frame to half-size on a temp surface + for (int yp = 0; yp < height / 2; ++yp) { + const uint16 *srcP = (const uint16 *)frame->getBasePtr(0, yp * 2); + uint16 *destP = (uint16 *)tempSurface.getBasePtr(0, yp); + + for (int xp = 0; xp < width / 2; ++xp, ++destP, srcP += 2) + *destP = *srcP; + } + + // Point the drawing frame to the temporary surface + frame = &tempSurface; + } + + g_system->copyRectToScreen(frame->getPixels(), frame->pitch, pos.x, pos.y, frame->w, frame->h); g_system->updateScreen(); } } diff --git a/engines/sherlock/scalpel/scalpel.h b/engines/sherlock/scalpel/scalpel.h index 1a208d7c0a..7bf3615c13 100644 --- a/engines/sherlock/scalpel/scalpel.h +++ b/engines/sherlock/scalpel/scalpel.h @@ -142,7 +142,7 @@ public: /** * Play back a 3do movie */ - bool play3doMovie(const Common::String &filename, const Common::Point &pos); + bool play3doMovie(const Common::String &filename, const Common::Point &pos, bool halfSize = false); }; } // End of namespace Scalpel diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp index 0c0feed12f..3f894d71a7 100644 --- a/engines/sherlock/scalpel/scalpel_talk.cpp +++ b/engines/sherlock/scalpel/scalpel_talk.cpp @@ -600,7 +600,7 @@ void ScalpelTalk::talk3DOMovieTrigger(int subIndex) { warning("selector: %d", selector); warning("subindex: %d", subIndex); - vm.play3doMovie(movieFilename, Common::Point(5, 5)); + vm.play3doMovie(movieFilename, Common::Point(5, 5), true); // Restore screen HACK _vm->_screen->makeAllDirty(); -- cgit v1.2.3