diff options
Diffstat (limited to 'engines/sherlock/scalpel/scalpel.cpp')
-rw-r--r-- | engines/sherlock/scalpel/scalpel.cpp | 600 |
1 files changed, 433 insertions, 167 deletions
diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index af9d613cce..cbb202095f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -21,16 +21,19 @@ */ #include "engines/util.h" +#include "gui/saveload.h" +#include "common/translation.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/scalpel/scalpel_fixed_text.h" #include "sherlock/scalpel/scalpel_map.h" #include "sherlock/scalpel/scalpel_people.h" #include "sherlock/scalpel/scalpel_scene.h" +#include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" #include "sherlock/scalpel/tsage/logo.h" #include "sherlock/sherlock.h" #include "sherlock/music.h" #include "sherlock/animation.h" -// for 3DO #include "sherlock/scalpel/3do/movie_decoder.h" namespace Sherlock { @@ -100,103 +103,177 @@ static const byte MAP_SEQUENCES[3][MAX_FRAME] = { struct PeopleData { const char *portrait; - const char *name; + int fixedTextId; byte stillSequences[MAX_TALK_SEQUENCES]; byte talkSequences[MAX_TALK_SEQUENCES]; }; const PeopleData PEOPLE_DATA[MAX_PEOPLE] = { - { "HOLM", "Sherlock Holmes", { 1, 0, 0 }, { 1, 0, 0 } }, - { "WATS", "Dr. Watson", { 6, 0, 0 }, { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 } }, - { "LEST", "Inspector Lestrade", { 4, 0, 0 }, { 2, 0, 0 } }, - { "CON1", "Constable O'Brien", { 2, 0, 0 }, { 1, 0, 0 } }, - { "CON2", "Constable Lewis", { 2, 0, 0 }, { 1, 0, 0 } }, - { "SHEI", "Sheila Parker", { 2, 0, 0 }, { 2, 3, 0, 0 } }, - { "HENR", "Henry Carruthers", { 3, 0, 0 }, { 3, 0, 0 } }, - { "LESL", "Lesley", { 9, 0, 0 }, { 1, 2, 3, 2, 1, 2, 3, 0, 0 } }, - { "USH1", "An Usher", { 13, 0, 0 }, { 13, 14, 0, 0 } }, - { "USH2", "An Usher", { 2, 0, 0 }, { 2, 0, 0 } }, - { "FRED", "Fredrick Epstein", { 4, 0, 0 }, { 1, 2, 3, 4, 3, 4, 3, 2, 0, 0 } }, - { "WORT", "Mrs. Worthington", { 9, 0, 0 }, { 8, 0, 0 } }, - { "COAC", "The Coach", { 2, 0, 0 }, { 1, 2, 3, 4, 5, 4, 3, 2, 0, 0 } }, - { "PLAY", "A Player", { 8, 0, 0 }, { 7, 8, 0, 0 } }, - { "WBOY", "Tim", { 13, 0, 0 }, { 12, 13, 0, 0 } }, - { "JAME", "James Sanders", { 6, 0, 0 }, { 3, 4, 0, 0 } }, - { "BELL", "Belle", { 1, 0, 0 }, { 4, 5, 0, 0 } }, - { "GIRL", "Cleaning Girl", { 20, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 20, 20, 0, 0 } }, - { "EPST", "Fredrick Epstein", { 17, 0, 0 }, { 16, 17, 18, 18, 18, 17, 17, 0, 0 } }, - { "WIGG", "Wiggins", { 3, 0, 0 }, { 2, 3, 0, 0 } }, - { "PAUL", "Paul", { 2, 0, 0 }, { 1, 2, 0, 0 } }, - { "BART", "The Bartender", { 1, 0, 0 }, { 1, 0, 0 } }, - { "DIRT", "A Dirty Drunk", { 1, 0, 0 }, { 1, 0, 0 } }, - { "SHOU", "A Shouting Drunk", { 1, 0, 0 }, { 1, 0, 0 } }, - { "STAG", "A Staggering Drunk", { 1, 0, 0 }, { 1, 0, 0 } }, - { "BOUN", "The Bouncer", { 1, 0, 0 }, { 1, 0, 0 } }, - { "SAND", "James Sanders", { 6, 0, 0 }, { 5, 6, 0, 0 } }, - { "CORO", "The Coroner", { 6, 0, 0 }, { 4, 5, 0, 0 } }, - { "EQUE", "Reginald Snipes", { 1, 0, 0 }, { 1, 0, 0 } }, - { "GEOR", "George Blackwood", { 1, 0, 0 }, { 1, 0, 0 } }, - { "LARS", "Lars", { 7, 0, 0 }, { 5, 6, 0, 0 } }, - { "PARK", "Sheila Parker", { 1, 0, 0 }, { 1, 0, 0 } }, - { "CHEM", "The Chemist", { 8, 0, 0 }, { 8, 9, 0, 0 } }, - { "GREG", "Inspector Gregson", { 6, 0, 0 }, { 5, 6, 0, 0 } }, - { "LAWY", "Jacob Farthington", { 1, 0, 0 }, { 1, 0, 0 } }, - { "MYCR", "Mycroft", { 1, 0, 0 }, { 1, 0, 0 } }, - { "SHER", "Old Sherman", { 7, 0, 0 }, { 7, 8, 0, 0 } }, - { "CHMB", "Richard", { 1, 0, 0 }, { 1, 0, 0 } }, - { "BARM", "The Barman", { 1, 0, 0 }, { 1, 0, 0 } }, - { "DAND", "A Dandy Player", { 1, 0, 0 }, { 1, 0, 0 } }, - { "ROUG", "A Rough-looking Player", { 1, 0, 0 }, { 1, 0, 0 } }, - { "SPEC", "A Spectator", { 1, 0, 0 }, { 1, 0, 0 } }, - { "HUNT", "Robert Hunt", { 1, 0, 0 }, { 1, 0, 0 } }, - { "VIOL", "Violet", { 3, 0, 0 }, { 3, 4, 0, 0 } }, - { "PETT", "Pettigrew", { 1, 0, 0 }, { 1, 0, 0 } }, - { "APPL", "Augie", { 8, 0, 0 }, { 14, 15, 0, 0 } }, - { "ANNA", "Anna Carroway", { 16, 0, 0 }, { 3, 4, 5, 6, 0, 0 } }, - { "GUAR", "A Guard", { 1, 0, 0 }, { 4, 5, 6, 0, 0 } }, - { "ANTO", "Antonio Caruso", { 8, 0, 0 }, { 7, 8, 0, 0 } }, - { "TOBY", "Toby the Dog", { 1, 0, 0 }, { 1, 0, 0 } }, - { "KING", "Simon Kingsley", { 13, 0, 0 }, { 13, 14, 0, 0 } }, - { "ALFR", "Alfred", { 2, 0, 0 }, { 2, 3, 0, 0 } }, - { "LADY", "Lady Brumwell", { 1, 0, 0 }, { 3, 4, 0, 0 } }, - { "ROSA", "Madame Rosa", { 1, 0, 0 }, { 1, 30, 0, 0 } }, - { "LADB", "Lady Brumwell", { 1, 0, 0 }, { 3, 4, 0, 0 } }, - { "MOOR", "Joseph Moorehead", { 1, 0, 0 }, { 1, 0, 0 } }, - { "BEAL", "Mrs. Beale", { 5, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 0, 0 } }, - { "LION", "Felix", { 1, 0, 0 }, { 1, 0, 0 } }, - { "HOLL", "Hollingston", { 1, 0, 0 }, { 1, 0, 0 } }, - { "CALL", "Constable Callaghan", { 1, 0, 0 }, { 1, 0, 0 } }, - { "JERE", "Sergeant Duncan", { 2, 0, 0 }, { 1, 1, 2, 2, 0, 0 } }, - { "LORD", "Lord Brumwell", { 1, 0, 0 }, { 9, 10, 0, 0 } }, - { "NIGE", "Nigel Jaimeson", { 1, 0, 0 }, { 1, 2, 0, 138, 3, 4, 0, 138, 0, 0 } }, - { "JONA", "Jonas", { 1, 0, 0 }, { 1, 8, 0, 0 } }, - { "DUGA", "Constable Dugan", { 1, 0, 0 }, { 1, 0, 0 } }, - { "INSP", "Inspector Lestrade", { 4, 0, 0 }, { 2, 0, 0 } } + { "HOLM", kFixedText_People_SherlockHolmes, { 1, 0, 0 }, { 1, 0, 0 } }, + { "WATS", kFixedText_People_DrWatson, { 6, 0, 0 }, { 5, 5, 6, 7, 8, 7, 8, 6, 0, 0 } }, + { "LEST", kFixedText_People_InspectorLestrade, { 4, 0, 0 }, { 2, 0, 0 } }, + { "CON1", kFixedText_People_ConstableOBrien, { 2, 0, 0 }, { 1, 0, 0 } }, + { "CON2", kFixedText_People_ConstableLewis, { 2, 0, 0 }, { 1, 0, 0 } }, + { "SHEI", kFixedText_People_SheilaParker, { 2, 0, 0 }, { 2, 3, 0, 0 } }, + { "HENR", kFixedText_People_HenryCarruthers, { 3, 0, 0 }, { 3, 0, 0 } }, + { "LESL", kFixedText_People_Lesley, { 9, 0, 0 }, { 1, 2, 3, 2, 1, 2, 3, 0, 0 } }, + { "USH1", kFixedText_People_AnUsher, { 13, 0, 0 }, { 13, 14, 0, 0 } }, + { "USH2", kFixedText_People_AnUsher, { 2, 0, 0 }, { 2, 0, 0 } }, + { "FRED", kFixedText_People_FredrickEpstein, { 4, 0, 0 }, { 1, 2, 3, 4, 3, 4, 3, 2, 0, 0 } }, + { "WORT", kFixedText_People_MrsWorthington, { 9, 0, 0 }, { 8, 0, 0 } }, + { "COAC", kFixedText_People_TheCoach, { 2, 0, 0 }, { 1, 2, 3, 4, 5, 4, 3, 2, 0, 0 } }, + { "PLAY", kFixedText_People_APlayer, { 8, 0, 0 }, { 7, 8, 0, 0 } }, + { "WBOY", kFixedText_People_Tim, { 13, 0, 0 }, { 12, 13, 0, 0 } }, + { "JAME", kFixedText_People_JamesSanders, { 6, 0, 0 }, { 3, 4, 0, 0 } }, + { "BELL", kFixedText_People_Belle, { 1, 0, 0 }, { 4, 5, 0, 0 } }, + { "GIRL", kFixedText_People_CleaningGirl, { 20, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 20, 20, 0, 0 } }, + { "EPST", kFixedText_People_FredrickEpstein, { 17, 0, 0 }, { 16, 17, 18, 18, 18, 17, 17, 0, 0 } }, + { "WIGG", kFixedText_People_Wiggins, { 3, 0, 0 }, { 2, 3, 0, 0 } }, + { "PAUL", kFixedText_People_Paul, { 2, 0, 0 }, { 1, 2, 0, 0 } }, + { "BART", kFixedText_People_TheBartender, { 1, 0, 0 }, { 1, 0, 0 } }, + { "DIRT", kFixedText_People_ADirtyDrunk, { 1, 0, 0 }, { 1, 0, 0 } }, + { "SHOU", kFixedText_People_AShoutingDrunk, { 1, 0, 0 }, { 1, 0, 0 } }, + { "STAG", kFixedText_People_AStaggeringDrunk, { 1, 0, 0 }, { 1, 0, 0 } }, + { "BOUN", kFixedText_People_TheBouncer, { 1, 0, 0 }, { 1, 0, 0 } }, + { "SAND", kFixedText_People_JamesSanders, { 6, 0, 0 }, { 5, 6, 0, 0 } }, + { "CORO", kFixedText_People_TheCoroner, { 6, 0, 0 }, { 4, 5, 0, 0 } }, + { "EQUE", kFixedText_People_ReginaldSnipes, { 1, 0, 0 }, { 1, 0, 0 } }, + { "GEOR", kFixedText_People_GeorgeBlackwood, { 1, 0, 0 }, { 1, 0, 0 } }, + { "LARS", kFixedText_People_Lars, { 7, 0, 0 }, { 5, 6, 0, 0 } }, + { "PARK", kFixedText_People_SheilaParker, { 1, 0, 0 }, { 1, 0, 0 } }, + { "CHEM", kFixedText_People_TheChemist, { 8, 0, 0 }, { 8, 9, 0, 0 } }, + { "GREG", kFixedText_People_InspectorGregson, { 6, 0, 0 }, { 5, 6, 0, 0 } }, + { "LAWY", kFixedText_People_JacobFarthington, { 1, 0, 0 }, { 1, 0, 0 } }, + { "MYCR", kFixedText_People_Mycroft, { 1, 0, 0 }, { 1, 0, 0 } }, + { "SHER", kFixedText_People_OldSherman, { 7, 0, 0 }, { 7, 8, 0, 0 } }, + { "CHMB", kFixedText_People_Richard, { 1, 0, 0 }, { 1, 0, 0 } }, + { "BARM", kFixedText_People_TheBarman, { 1, 0, 0 }, { 1, 0, 0 } }, + { "DAND", kFixedText_People_ADandyPlayer, { 1, 0, 0 }, { 1, 0, 0 } }, + { "ROUG", kFixedText_People_ARoughlookingPlayer, { 1, 0, 0 }, { 1, 0, 0 } }, + { "SPEC", kFixedText_People_ASpectator, { 1, 0, 0 }, { 1, 0, 0 } }, + { "HUNT", kFixedText_People_RobertHunt, { 1, 0, 0 }, { 1, 0, 0 } }, + { "VIOL", kFixedText_People_Violet, { 3, 0, 0 }, { 3, 4, 0, 0 } }, + { "PETT", kFixedText_People_Pettigrew, { 1, 0, 0 }, { 1, 0, 0 } }, + { "APPL", kFixedText_People_Augie, { 8, 0, 0 }, { 14, 15, 0, 0 } }, + { "ANNA", kFixedText_People_AnnaCarroway, { 16, 0, 0 }, { 3, 4, 5, 6, 0, 0 } }, + { "GUAR", kFixedText_People_AGuard, { 1, 0, 0 }, { 4, 5, 6, 0, 0 } }, + { "ANTO", kFixedText_People_AntonioCaruso, { 8, 0, 0 }, { 7, 8, 0, 0 } }, + { "TOBY", kFixedText_People_TobyTheDog, { 1, 0, 0 }, { 1, 0, 0 } }, + { "KING", kFixedText_People_SimonKingsley, { 13, 0, 0 }, { 13, 14, 0, 0 } }, + { "ALFR", kFixedText_People_Alfred, { 2, 0, 0 }, { 2, 3, 0, 0 } }, + { "LADY", kFixedText_People_LadyBrumwell, { 1, 0, 0 }, { 3, 4, 0, 0 } }, + { "ROSA", kFixedText_People_MadameRosa, { 1, 0, 0 }, { 1, 30, 0, 0 } }, + { "LADB", kFixedText_People_LadyBrumwell, { 1, 0, 0 }, { 3, 4, 0, 0 } }, + { "MOOR", kFixedText_People_JosephMoorehead, { 1, 0, 0 }, { 1, 0, 0 } }, + { "BEAL", kFixedText_People_MrsBeale, { 5, 0, 0 }, { 14, 15, 16, 17, 18, 19, 20, 0, 0 } }, + { "LION", kFixedText_People_Felix, { 1, 0, 0 }, { 1, 0, 0 } }, + { "HOLL", kFixedText_People_Hollingston, { 1, 0, 0 }, { 1, 0, 0 } }, + { "CALL", kFixedText_People_ConstableCallaghan, { 1, 0, 0 }, { 1, 0, 0 } }, + { "JERE", kFixedText_People_SergeantDuncan, { 2, 0, 0 }, { 1, 1, 2, 2, 0, 0 } }, + { "LORD", kFixedText_People_LordBrumwell, { 1, 0, 0 }, { 9, 10, 0, 0 } }, + { "NIGE", kFixedText_People_NigelJaimeson, { 1, 0, 0 }, { 1, 2, 0, 138, 3, 4, 0, 138, 0, 0 } }, + { "JONA", kFixedText_People_Jonas, { 1, 0, 0 }, { 1, 8, 0, 0 } }, + { "DUGA", kFixedText_People_ConstableDugan, { 1, 0, 0 }, { 1, 0, 0 } }, + { "INSP", kFixedText_People_InspectorLestrade, { 4, 0, 0 }, { 2, 0, 0 } } }; +uint INFO_BLACK; +uint BORDER_COLOR; +uint COMMAND_BACKGROUND; +uint BUTTON_BACKGROUND; +uint TALK_FOREGROUND; +uint TALK_NULL; +uint BUTTON_TOP; +uint BUTTON_MIDDLE; +uint BUTTON_BOTTOM; +uint COMMAND_FOREGROUND; +uint COMMAND_HIGHLIGHTED; +uint COMMAND_NULL; +uint INFO_FOREGROUND; +uint INFO_BACKGROUND; +uint INV_FOREGROUND; +uint INV_BACKGROUND; +uint PEN_COLOR; + /*----------------------------------------------------------------*/ +#define FROM_RGB(r, g, b) pixelFormatRGB565.RGBToColor(r, g, b) + ScalpelEngine::ScalpelEngine(OSystem *syst, const SherlockGameDescription *gameDesc) : SherlockEngine(syst, gameDesc) { _darts = nullptr; _mapResult = 0; + + if (getPlatform() == Common::kPlatform3DO) { + const Graphics::PixelFormat pixelFormatRGB565 = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + INFO_BLACK = FROM_RGB(0, 0, 0); + BORDER_COLOR = FROM_RGB(0x6d, 0x38, 0x10); + COMMAND_BACKGROUND = FROM_RGB(0x38, 0x38, 0xce); + BUTTON_BACKGROUND = FROM_RGB(0x95, 0x5d, 0x24); + TALK_FOREGROUND = FROM_RGB(0xff, 0x55, 0x55); + TALK_NULL = FROM_RGB(0xce, 0xc6, 0xc2); + BUTTON_TOP = FROM_RGB(0xbe, 0x85, 0x3c); + BUTTON_MIDDLE = FROM_RGB(0x9d, 0x40, 0); + BUTTON_BOTTOM = FROM_RGB(0x69, 0x24, 0); + COMMAND_FOREGROUND = FROM_RGB(0xFF, 0xFF, 0xFF); + COMMAND_HIGHLIGHTED = FROM_RGB(0x55, 0xff, 0x55); + COMMAND_NULL = FROM_RGB(0x69, 0x24, 0); + INFO_FOREGROUND = FROM_RGB(0x55, 0xff, 0xff); + INFO_BACKGROUND = FROM_RGB(0, 0, 0x48); + INV_FOREGROUND = FROM_RGB(0xff, 0xff, 0x55); + INV_BACKGROUND = FROM_RGB(0, 0, 0x48); + PEN_COLOR = FROM_RGB(0x50, 0x18, 0); + } else { + INFO_BLACK = 1; + BORDER_COLOR = 237; + COMMAND_BACKGROUND = 4; + BUTTON_BACKGROUND = 235; + TALK_FOREGROUND = 12; + TALK_NULL = 16; + BUTTON_TOP = 233; + BUTTON_MIDDLE = 244; + BUTTON_BOTTOM = 248; + COMMAND_FOREGROUND = 15; + COMMAND_HIGHLIGHTED = 10; + COMMAND_NULL = 248; + INFO_FOREGROUND = 11; + INFO_BACKGROUND = 1; + INV_FOREGROUND = 14; + INV_BACKGROUND = 1; + PEN_COLOR = 250; + } } ScalpelEngine::~ScalpelEngine() { delete _darts; } -void ScalpelEngine::initialize() { - // 3DO actually uses RGB555, but some platforms of ours only support RGB565, so we use that - - if (getPlatform() == Common::kPlatform3DO) { - const Graphics::PixelFormat pixelFormatRGB565 = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); - // 320x200 16-bit RGB565 for 3DO support - initGraphics(320, 200, false, &pixelFormatRGB565); - } else { +void ScalpelEngine::setupGraphics() { + if (getPlatform() != Common::kPlatform3DO) { // 320x200 palettized initGraphics(320, 200, false); + } else { + // 3DO actually uses RGB555, but some platforms of ours only support RGB565, so we use that + const Graphics::PixelFormat pixelFormatRGB565 = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); + + // First try for a 640x400 mode + g_system->beginGFXTransaction(); + initCommonGFX(true); + g_system->initSize(640, 400, &pixelFormatRGB565); + OSystem::TransactionError gfxError = g_system->endGFXTransaction(); + + if (gfxError == OSystem::kTransactionSuccess) { + _isScreenDoubled = true; + } else { + // System doesn't support it, so fall back on 320x200 mode + initGraphics(320, 200, false, &pixelFormatRGB565); + } } +} + +void ScalpelEngine::initialize() { + // Setup graphics mode + setupGraphics(); // Let the base engine intialize SherlockEngine::initialize(); @@ -219,9 +296,14 @@ void ScalpelEngine::initialize() { loadInventory(); // Set up list of people - for (int idx = 0; idx < MAX_PEOPLE; ++idx) - _people->_characters.push_back(PersonData(PEOPLE_DATA[idx].name, PEOPLE_DATA[idx].portrait, + ScalpelFixedText &fixedText = *(ScalpelFixedText *)_fixedText; + const char *peopleNamePtr = nullptr; + + for (int idx = 0; idx < MAX_PEOPLE; ++idx) { + peopleNamePtr = fixedText.getText(PEOPLE_DATA[idx].fixedTextId); + _people->_characters.push_back(PersonData(peopleNamePtr, PEOPLE_DATA[idx].portrait, PEOPLE_DATA[idx].stillSequences, PEOPLE_DATA[idx].talkSequences)); + } _animation->setPrologueNames(&PROLOGUE_NAMES[0], PROLOGUE_NAMES_COUNT); _animation->setPrologueFrames(&PROLOGUE_FRAMES[0][0], 6, 9); @@ -242,6 +324,8 @@ void ScalpelEngine::showOpening() { if (isDemo() && _interactiveFl) return; + _events->setFrameRate(60); + if (getPlatform() == Common::kPlatform3DO) { show3DOSplash(); @@ -255,20 +339,22 @@ void ScalpelEngine::showOpening() { _events->clearEvents(); _music->stopMusic(); - return; - } + } else { + TsAGE::Logo::show(this); - TsAGE::Logo::show(this); - finished = showCityCutscene(); - if (finished) - finished = showAlleyCutscene(); - if (finished) - finished = showStreetCutscene(); - if (finished) - showOfficeCutscene(); + finished = showCityCutscene(); + if (finished) + finished = showAlleyCutscene(); + if (finished) + finished = showStreetCutscene(); + if (finished) + showOfficeCutscene(); - _events->clearEvents(); - _music->stopMusic(); + _events->clearEvents(); + _music->stopMusic(); + } + + _events->setFrameRate(GAME_FRAME_RATE); } bool ScalpelEngine::showCityCutscene() { @@ -286,8 +372,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages_LondonNovember("title2.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); + _screen->_backBuffer2.SHblitFrom(*_screen); Common::Point londonPosition; @@ -301,19 +387,19 @@ bool ScalpelEngine::showCityCutscene() { } // London, England - _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[0], londonPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_LondonNovember[0], londonPosition); _screen->randomTransition(); finished = _events->delay(1000, true); // November, 1888 if (finished) { - _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[1], Common::Point(100, 100)); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_LondonNovember[1], Common::Point(100, 100)); _screen->randomTransition(); finished = _events->delay(5000, true); } // Transition out the title - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2); _screen->randomTransition(); } @@ -322,8 +408,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages_SherlockHolmesTitle("title.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); + _screen->_backBuffer2.SHblitFrom(*_screen); Common::Point lostFilesPosition; Common::Point sherlockHolmesPosition; @@ -342,17 +428,17 @@ bool ScalpelEngine::showCityCutscene() { } // The Lost Files of - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[0], lostFilesPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[0], lostFilesPosition); // Sherlock Holmes - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[1], sherlockHolmesPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[1], sherlockHolmesPosition); // copyright - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[2], copyrightPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[2], copyrightPosition); _screen->verticalTransition(); finished = _events->delay(4000, true); if (finished) { - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2); _screen->randomTransition(); finished = _events->delay(2000); } @@ -376,7 +462,7 @@ bool ScalpelEngine::showCityCutscene() { // English, width 175, height 38 alleyPosition = Common::Point(72, 51); } - _screen->transBlitFrom(titleImages_SherlockHolmesTitle[3], alleyPosition); + _screen->SHtransBlitFrom(titleImages_SherlockHolmesTitle[3], alleyPosition); _screen->fadeIn(palette, 3); // Wait until the track got looped and the first few notes were played @@ -452,7 +538,7 @@ bool ScalpelEngine::showAlleyCutscene() { earlyTheFollowingMorningPosition = Common::Point(35, 52); } - _screen->transBlitFrom(titleImages_EarlyTheFollowingMorning[0], earlyTheFollowingMorningPosition); + _screen->SHtransBlitFrom(titleImages_EarlyTheFollowingMorning[0], earlyTheFollowingMorningPosition); // fast fade-in _screen->fadeIn(palette, 1); @@ -556,23 +642,23 @@ bool ScalpelEngine::scrollCredits() { delete stream; // Save a copy of the screen background for use in drawing each credit frame - _screen->_backBuffer1.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); // Loop for showing the credits for(int idx = 0; idx < 600 && !_events->kbHit() && !shouldQuit(); ++idx) { // Copy the entire screen background before writing text - _screen->blitFrom(_screen->_backBuffer1); + _screen->SHblitFrom(_screen->_backBuffer1); // Write the text appropriate for the next frame if (idx < 400) - _screen->transBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0); + _screen->SHtransBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0); if (idx > 200) - _screen->transBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); + _screen->SHtransBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); // Don't show credit text on the top and bottom ten rows of the screen - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->w(), 10)); - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, _screen->h() - 10), - Common::Rect(0, _screen->h() - 10, _screen->w(), _screen->h())); + _screen->SHblitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->width(), 10)); + _screen->SHblitFrom(_screen->_backBuffer1, Common::Point(0, _screen->height() - 10), + Common::Rect(0, _screen->height() - 10, _screen->width(), _screen->height())); _events->delay(100); } @@ -585,7 +671,7 @@ bool ScalpelEngine::show3DOSplash() { // 3DO EA Splash screen ImageFile3DO titleImage_3DOSplash("3DOSplash.cel", kImageFile3DOType_Cel); - _screen->transBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20)); + _screen->SHtransBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20)); bool finished = _events->delay(3000, true); if (finished) { @@ -595,7 +681,7 @@ bool ScalpelEngine::show3DOSplash() { if (finished) { // EA logo movie - Scalpel3DOMoviePlay("EAlogo.stream", Common::Point(20, 0)); + play3doMovie("EAlogo.stream", Common::Point(20, 0)); } // Always clear screen @@ -604,23 +690,25 @@ bool ScalpelEngine::show3DOSplash() { } bool ScalpelEngine::showCityCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; _animation->_soundLibraryFilename = "TITLE.SND"; - _screen->clear(); + screen.clear(); bool finished = _events->delay(2500, true); - // rain.aiff seems to be playing in an endless loop until - // sherlock logo fades away TODO - if (finished) { finished = _events->delay(2500, true); // Play intro music _music->loadSong("prolog"); + // Loop rain.aiff until the Sherlock logo fades away. + // TODO: The volume is just a guess. + _sound->playAiff("prologue/sounds/rain.aiff", 15, true); + // Fade screen to grey - _screen->_backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey) - _screen->fadeIntoScreen3DO(2); + screen._backBuffer1.clear(0xCE59); // RGB565: 25, 50, 25 (grey) + screen.fadeIntoScreen3DO(2); } if (finished) { @@ -628,33 +716,33 @@ bool ScalpelEngine::showCityCutscene3DO() { } if (finished) { - _screen->_backBuffer1.fill(0); // fill backbuffer with black to avoid issues during fade from white + screen._backBuffer1.clear(0); // fill backbuffer with black to avoid issues during fade from white finished = _animation->play3DO("26open1", true, 1, true, 2); } if (finished) { - _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade - _screen->_backBuffer2.blitFrom(*_screen); // save into backbuffer 2, for restoring later + screen._backBuffer2.SHblitFrom(screen._backBuffer1); // "London, England" ImageFile3DO titleImage_London("title2a.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); + screen._backBuffer1.SHtransBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); - _screen->fadeIntoScreen3DO(1); + screen.fadeIntoScreen3DO(1); finished = _events->delay(1500, true); if (finished) { // "November, 1888" ImageFile3DO titleImage_November("title2b.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); + screen._backBuffer1.SHtransBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); - _screen->fadeIntoScreen3DO(1); + screen.fadeIntoScreen3DO(1); finished = _music->waitUntilMSec(14700, 0, 0, 5000); } if (finished) { // Restore screen - _screen->blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.SHblitFrom(screen._backBuffer2); + _screen->SHblitFrom(screen._backBuffer1); } } @@ -662,21 +750,19 @@ bool ScalpelEngine::showCityCutscene3DO() { finished = _animation->play3DO("26open2", true, 1, false, 2); if (finished) { - _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade - // "Sherlock Holmes" (title) ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); + screen._backBuffer1.SHtransBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); // Blend in - _screen->fadeIntoScreen3DO(2); + screen.fadeIntoScreen3DO(2); finished = _events->delay(500, true); // Title should fade in, Copyright should be displayed a bit after that if (finished) { ImageFile3DO titleImage_Copyright("title1c.cel", kImageFile3DOType_Cel); - _screen->transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); + screen.SHtransBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); finished = _events->delay(3500, true); } } @@ -684,29 +770,32 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) finished = _music->waitUntilMSec(33600, 0, 0, 2000); + _sound->stopAiff(); + if (finished) { // Fade to black - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(3); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(3); } if (finished) { // "In the alley behind the Regency Theatre..." ImageFile3DO titleImage_InTheAlley("title1d.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); + screen._backBuffer1.SHtransBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); // Fade in - _screen->fadeIntoScreen3DO(4); + screen.fadeIntoScreen3DO(4); finished = _music->waitUntilMSec(39900, 0, 0, 2500); // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); } return finished; } bool ScalpelEngine::showAlleyCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; bool finished = _music->waitUntilMSec(43500, 0, 0, 1000); if (finished) @@ -714,8 +803,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out... - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(3); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(3); finished = _music->waitUntilMSec(67100, 0, 0, 1000); // 66700 } @@ -730,8 +819,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { // Show screaming victim ImageFile3DO titleImage_ScreamingVictim("scream.cel", kImageFile3DOType_Cel); - _screen->clear(); - _screen->transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); + screen.clear(); + screen.SHtransBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); // Play "scream.aiff" if (_sound->_voices) @@ -742,8 +831,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(5); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(5); finished = _music->waitUntilMSec(84400, 0, 0, 2000); } @@ -753,17 +842,17 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(5); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(5); } if (finished) { // "Early the following morning on Baker Street..." ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); + screen._backBuffer1.SHtransBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); // Fade in - _screen->fadeIntoScreen3DO(4); + screen.fadeIntoScreen3DO(4); finished = _music->waitUntilMSec(96700, 0, 0, 3000); } @@ -771,12 +860,13 @@ bool ScalpelEngine::showAlleyCutscene3DO() { } bool ScalpelEngine::showStreetCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; bool finished = true; if (finished) { // fade out "Early the following morning..." - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); // wait for music a bit finished = _music->waitUntilMSec(100300, 0, 0, 1000); @@ -795,8 +885,8 @@ bool ScalpelEngine::showStreetCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); } return finished; @@ -819,7 +909,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() { ImageFile3DO titleImage_CoffeeNote("note.cel", kImageFile3DOType_Cel); _screen->clear(); - _screen->transBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0)); + _screen->SHtransBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0)); if (_sound->_voices) { finished = _sound->playSound("prologue/sounds/note.aiff", WAIT_KBD_OR_FINISH); @@ -848,7 +938,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() { // TODO: Brighten the image, possibly by doing a partial fade // to white. - _screen->_backBuffer1.blitFrom(*_screen); + _screen->_backBuffer2.SHblitFrom(_screen->_backBuffer1); for (int nr = 1; finished && nr <= 4; nr++) { char filename[15]; @@ -856,8 +946,8 @@ bool ScalpelEngine::showOfficeCutscene3DO() { ImageFile3DO *creditsImage = new ImageFile3DO(filename, kImageFile3DOType_Cel); ImageFrame *creditsFrame = &(*creditsImage)[0]; for (int i = 0; finished && i < 200 + creditsFrame->_height; i++) { - _screen->blitFrom(_screen->_backBuffer1); - _screen->transBlitFrom(creditsFrame->_frame, Common::Point((320 - creditsFrame->_width) / 2, 200 - i)); + _screen->SHblitFrom(_screen->_backBuffer2); + _screen->SHtransBlitFrom(creditsFrame->_frame, Common::Point((320 - creditsFrame->_width) / 2, 200 - i)); if (!_events->delay(70, true)) finished = false; } @@ -909,7 +999,7 @@ void ScalpelEngine::showLBV(const Common::String &filename) { delete stream; _screen->setPalette(images._palette); - _screen->_backBuffer1.blitFrom(images[0]); + _screen->_backBuffer1.SHblitFrom(images[0]); _screen->verticalTransition(); } @@ -1062,17 +1152,17 @@ void ScalpelEngine::startScene() { _mapResult = _scene->_goToScene; } -void ScalpelEngine::eraseMirror12() { +void ScalpelEngine::eraseBrumwellMirror() { Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER); // If player is in range of the mirror, then restore background from the secondary back buffer if (Common::Rect(70, 100, 200, 200).contains(pt)) { - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(137, 18), Common::Rect(137, 18, 184, 74)); } } -void ScalpelEngine::doMirror12() { +void ScalpelEngine::doBrumwellMirror() { People &people = *_people; Person &player = people[HOLMES]; @@ -1129,25 +1219,25 @@ void ScalpelEngine::doMirror12() { bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT || people[HOLMES]._sequenceNumber == WALK_UPRIGHT || people[HOLMES]._sequenceNumber == STOP_UPRIGHT || people[HOLMES]._sequenceNumber == WALK_DOWNLEFT || people[HOLMES]._sequenceNumber == STOP_DOWNLEFT; - _screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); + _screen->_backBuffer1.SHtransBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(114, 18), Common::Rect(114, 18, 137, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(137, 70), Common::Rect(137, 70, 142, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(142, 71), Common::Rect(142, 71, 159, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(159, 72), Common::Rect(159, 72, 170, 116)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(170, 73), Common::Rect(170, 73, 184, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(184, 18), Common::Rect(184, 18, 212, 114)); } } -void ScalpelEngine::flushMirror12() { +void ScalpelEngine::flushBrumwellMirror() { Common::Point pt((*_people)[HOLMES]._position.x / FIXED_INT_MULTIPLIER, (*_people)[HOLMES]._position.y / FIXED_INT_MULTIPLIER); // If player is in range of the mirror, then draw the entire mirror area to the screen @@ -1155,6 +1245,182 @@ void ScalpelEngine::flushMirror12() { _screen->slamArea(137, 18, 47, 56); } + +void ScalpelEngine::showScummVMSaveDialog() { + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + + int slot = dialog->runModalWithCurrentTarget(); + if (slot >= 0) { + Common::String desc = dialog->getResultString(); + + saveGameState(slot, desc); + } + + delete dialog; +} + +void ScalpelEngine::showScummVMRestoreDialog() { + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + + int slot = dialog->runModalWithCurrentTarget(); + if (slot >= 0) { + loadGameState(slot); + } + + delete dialog; +} + +bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::Point &pos, bool isPortrait) { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; + Scalpel3DOMovieDecoder *videoDecoder = new Scalpel3DOMovieDecoder(); + Graphics::ManagedSurface tempSurface; + + Common::Point framePos(pos.x, pos.y); + ImageFile3DO *frameImageFile = nullptr; + ImageFrame *frameImage = nullptr; + bool frameShown = false; + + if (!videoDecoder->loadFile(filename)) { + warning("Scalpel3DOMoviePlay: could not open '%s'", filename.c_str()); + return false; + } + + bool halfSize = isPortrait && !_isScreenDoubled; + if (isPortrait) { + // only for portrait videos, not for EA intro logo and such + if ((framePos.x >= 8) && (framePos.y >= 8)) { // safety check + framePos.x -= 8; + framePos.y -= 8; // frame is 8 pixels on left + top, and 7 pixels on right + bottom + } + + frameImageFile = new ImageFile3DO("vidframe.cel", kImageFile3DOType_Cel); + frameImage = &(*frameImageFile)[0]; + } + + bool skipVideo = false; + //byte bytesPerPixel = videoDecoder->getPixelFormat().bytesPerPixel; + uint16 width = videoDecoder->getWidth(); + uint16 height = videoDecoder->getHeight(); + //uint16 pitch = videoDecoder->getWidth() * bytesPerPixel; + + _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); + + while (!shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { + if (videoDecoder->needsUpdate()) { + const Graphics::Surface *frame = videoDecoder->decodeNextFrame(); + + if (frame) { + if (halfSize) { + // movies are 152 x 200 + + // Downscale, but calculate average color out of 4 pixels and put that average into the target pixel + // TODO: 3DO actually did pixel weighting, exact details about this are unknown + // It's also unknown what 3DO exactly did for interpolation + // and it's also unknown atm if the CinePak videos contained pixel weighting information + + if ((height & 1) || (width & 1)) { + error("Scalpel3DOMoviePlay: critical error, half-size requested on video with uneven height/width"); + } + + for (int downscaleY = 0; downscaleY < height / 2; downscaleY++) { + const uint16 *downscaleSource1Ptr = (const uint16 *)frame->getBasePtr(0, downscaleY * 2); + const uint16 *downscaleSource2Ptr = (const uint16 *)frame->getBasePtr(0, (downscaleY * 2) + 1); + uint16 *downscaleTargetPtr = (uint16 *)tempSurface.getBasePtr(0, downscaleY); + + for (int downscaleX = 0; downscaleX < width / 2; downscaleX++) { + // get 4 pixel colors + uint16 downscaleColor = *downscaleSource1Ptr; + uint32 downscaleRed = downscaleColor >> 11; // 5 bits + uint32 downscaleGreen = (downscaleColor >> 5) & 0x3f; // 6 bits + uint32 downscaleBlue = downscaleColor & 0x1f; + + downscaleSource1Ptr++; + downscaleColor = *downscaleSource1Ptr; + downscaleRed += downscaleColor >> 11; + downscaleGreen += (downscaleColor >> 5) & 0x3f; + downscaleBlue += downscaleColor & 0x1f; + + downscaleColor = *downscaleSource2Ptr; + downscaleRed += downscaleColor >> 11; + downscaleGreen += (downscaleColor >> 5) & 0x3f; + downscaleBlue += downscaleColor & 0x1f; + + downscaleSource2Ptr++; + downscaleColor = *downscaleSource2Ptr; + downscaleRed += downscaleColor >> 11; + downscaleGreen += (downscaleColor >> 5) & 0x3f; + downscaleBlue += downscaleColor & 0x1f; + + // Divide colors by 4, so that we get the average + downscaleRed = downscaleRed >> 2; + downscaleGreen = downscaleGreen >> 2; + downscaleBlue = downscaleBlue >> 2; + + // write new color to target pixel + downscaleColor = (downscaleRed << 11) | (downscaleGreen << 5) | downscaleBlue; + *downscaleTargetPtr = downscaleColor; + + downscaleSource1Ptr++; + downscaleSource2Ptr++; + downscaleTargetPtr++; + } + } + + // Point the drawing frame to the temporary surface + frame = &tempSurface.rawSurface(); + } + + if (isPortrait && !frameShown) { + // Draw the frame (not the frame of the video, but a frame around the video) itself + _screen->SHtransBlitFrom(frameImage->_frame, framePos); + frameShown = true; + } + + if (isPortrait && !halfSize) { + screen.rawBlitFrom(*frame, Common::Point(pos.x * 2, pos.y * 2)); + } else { + _screen->SHblitFrom(*frame, pos); + } + + _screen->update(); + } + } + + _events->pollEventsAndWait(); + _events->setButtonState(); + + if (_events->kbHit()) { + Common::KeyState keyState = _events->getKey(); + if (keyState.keycode == Common::KEYCODE_ESCAPE) + skipVideo = true; + } else if (_events->_pressed) { + skipVideo = true; + } + } + + if (halfSize) + tempSurface.free(); + + videoDecoder->close(); + delete videoDecoder; + + if (isPortrait) { + delete frameImageFile; + } + + // Restore scene + screen._backBuffer1.SHblitFrom(screen._backBuffer2); + _scene->updateBackground(); + screen.slamArea(0, 0, screen.width(), CONTROLS_Y); + + return !skipVideo; +} + } // End of namespace Scalpel } // End of namespace Sherlock |