From 2d74128069453e2872723f6ca15ffdf428e5be5d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 21 Sep 2016 21:14:25 -0400 Subject: XEEN: Implemented Clouds intro, doScroll fixes --- engines/xeen/cutscenes.cpp | 66 +++++----- engines/xeen/cutscenes.h | 5 +- engines/xeen/dialogs.cpp | 11 +- engines/xeen/dialogs.h | 5 +- engines/xeen/worldofxeen/clouds_cutscenes.cpp | 182 ++++++++++++++++++++++++-- engines/xeen/worldofxeen/clouds_cutscenes.h | 5 + 6 files changed, 225 insertions(+), 49 deletions(-) (limited to 'engines') diff --git a/engines/xeen/cutscenes.cpp b/engines/xeen/cutscenes.cpp index 0579af2b4d..3c49d12816 100644 --- a/engines/xeen/cutscenes.cpp +++ b/engines/xeen/cutscenes.cpp @@ -114,98 +114,100 @@ uint Cutscenes::getSpeakingFrame(uint minFrame, uint maxFrame) { return minFrame + interval % (maxFrame + 1 - minFrame); } -void Cutscenes::doScroll(bool drawFlag, bool doFade) { +bool Cutscenes::doScroll(bool rollUp, bool fadeIn) { Screen &screen = *_vm->_screen; EventsManager &events = *_vm->_events; + const int SCROLL_L[8] = { 29, 23, 15, -5, -11, -23, -49, -71 }; + const int SCROLL_R[8] = { 165, 171, 198, 218, 228, 245, 264, 281 }; - if (_vm->getGameID() != GType_Clouds) { - if (doFade) { + if (_vm->_files->_isDarkCc) { + if (fadeIn) screen.fadeIn(2); - } - return; + return _vm->shouldQuit(); } - const int SCROLL_L[8] = { 29, 23, 15, 251, 245, 233, 207, 185 }; - const int SCROLL_R[8] = { 165, 171, 198, 218, 228, 245, 264, 281 }; - screen.saveBackground(); - // Load hand vga files + // Load hand sprites SpriteResource *hand[16]; for (int i = 0; i < 16; ++i) { Common::String name = Common::String::format("hand%02d.vga", i); hand[i] = new SpriteResource(name); } - // Load marb vga files + // Load marb sprites SpriteResource *marb[5]; - for (int i = 1; i < 5; ++i) { - Common::String name = Common::String::format("marb%02d.vga", i); + for (int i = 0; i < 4; ++i) { + Common::String name = Common::String::format("marb%02d.vga", i + 1); marb[i] = new SpriteResource(name); } - if (drawFlag) { - for (int i = 22; i > 0; --i) { + if (rollUp) { + for (int i = 22, ctr = 7; i > 0 && !events.isKeyMousePressed() + && !_vm->shouldQuit(); --i) { events.updateGameCounter(); screen.restoreBackground(); - if (i > 0 && i <= 14) { + if (i > 14) { + hand[14]->draw(screen, 0, Common::Point(SCROLL_L[ctr], 0), SPRFLAG_800); + hand[15]->draw(screen, 0, Common::Point(SCROLL_R[ctr], 0), SPRFLAG_800); + --ctr; + } else if (i != 0) { hand[i - 1]->draw(screen, 0); - } else { - hand[14]->draw(screen, 0, Common::Point(SCROLL_L[i - 14], 0), SPRFLAG_800); - marb[15]->draw(screen, 0, Common::Point(SCROLL_R[i - 14], 0), SPRFLAG_800); } - if (i <= 20) { - marb[i / 5]->draw(screen, i % 5); - } + if (i <= 20) + marb[(i - 1) / 5]->draw(screen, (i - 1) % 5); + screen.update(); while (!_vm->shouldQuit() && events.timeElapsed() == 0) events.pollEventsAndWait(); - screen._windows[0].update(); - if (i == 0 && doFade) + if (i == 0 && fadeIn) screen.fadeIn(2); } } else { - for (int i = 0; i < 22 && !events.isKeyMousePressed(); ++i) { + for (int i = 0, ctr = 0; i < 22 && !events.isKeyMousePressed() + && !_vm->shouldQuit(); ++i) { events.updateGameCounter(); screen.restoreBackground(); if (i < 14) { hand[i]->draw(screen, 0); } else { - hand[14]->draw(screen, 0, Common::Point(SCROLL_L[i - 7], 0), SPRFLAG_800); - marb[15]->draw(screen, 0, Common::Point(SCROLL_R[i - 7], 0), SPRFLAG_800); + hand[14]->draw(screen, 0, Common::Point(SCROLL_L[ctr], 0), SPRFLAG_800); + hand[15]->draw(screen, 0, Common::Point(SCROLL_R[ctr], 0), SPRFLAG_800); + ++ctr; } if (i < 20) { marb[i / 5]->draw(screen, i % 5); } + screen.update(); while (!_vm->shouldQuit() && events.timeElapsed() == 0) events.pollEventsAndWait(); - screen._windows[0].update(); - if (i == 0 && doFade) + if (i == 0 && fadeIn) screen.fadeIn(2); } } - if (drawFlag) { + if (rollUp) { hand[0]->draw(screen, 0); marb[0]->draw(screen, 0); } else { screen.restoreBackground(); } - - screen._windows[0].update(); + screen.update(); // Free resources - for (int i = 1; i < 5; ++i) + for (int i = 0; i < 4; ++i) delete marb[i]; for (int i = 0; i < 16; ++i) delete hand[i]; + + return _vm->shouldQuit() || events.isKeyMousePressed(); } } // End of namespace Xeen diff --git a/engines/xeen/cutscenes.h b/engines/xeen/cutscenes.h index a69fda5e8a..aa5501442d 100644 --- a/engines/xeen/cutscenes.h +++ b/engines/xeen/cutscenes.h @@ -90,8 +90,11 @@ protected: /** * Draws the scroll in the background + * @param rollUp If true, rolls up the scroll. If false, unrolls. + * @param fadeIn If true, does an initial fade in + * @returns True if key or mouse pressed */ - virtual void doScroll(bool drawFlag, bool doFade); + virtual bool doScroll(bool rollUp, bool fadeIn); }; } // End of namespace Xeen diff --git a/engines/xeen/dialogs.cpp b/engines/xeen/dialogs.cpp index 02546adabd..1ea08115f4 100644 --- a/engines/xeen/dialogs.cpp +++ b/engines/xeen/dialogs.cpp @@ -107,14 +107,15 @@ void ButtonContainer::drawButtons(XSurface *surface) { } } -void ButtonContainer::doScroll(bool drawFlag, bool doFade) { - if (_vm->getGameID() == GType_Clouds) { +bool ButtonContainer::doScroll(bool rollUp, bool fadeIn) { + if (_vm->_files->_isDarkCc) { + return Cutscenes::doScroll(rollUp, fadeIn); + } else { saveButtons(); clearButtons(); - Cutscenes::doScroll(drawFlag, doFade); + bool result = Cutscenes::doScroll(rollUp, fadeIn); restoreButtons(); - } else { - Cutscenes::doScroll(drawFlag, doFade); + return result; } } diff --git a/engines/xeen/dialogs.h b/engines/xeen/dialogs.h index 93e9a86685..921c72a33f 100644 --- a/engines/xeen/dialogs.h +++ b/engines/xeen/dialogs.h @@ -58,8 +58,11 @@ protected: /** * Draws the scroll in the background + * @param rollUp If true, rolls up the scroll. If false, unrolls. + * @param fadeIn If true, does an initial fade in + * @returns True if key or mouse pressed */ - virtual void doScroll(bool drawFlag, bool doFade); + virtual bool doScroll(bool rollUp, bool fadeIn); public: ButtonContainer(XeenEngine *vm) : Cutscenes(vm), _buttonValue(0) {} diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.cpp b/engines/xeen/worldofxeen/clouds_cutscenes.cpp index d9f03443c6..7b73e12e0e 100644 --- a/engines/xeen/worldofxeen/clouds_cutscenes.cpp +++ b/engines/xeen/worldofxeen/clouds_cutscenes.cpp @@ -91,6 +91,7 @@ bool CloudsCutscenes::showCloudsIntro() { lake("lake.vga"), xeen("xeen.vga"), wizTower("wiztower.vga"), wizTower2("wiztwer2.vga"), lake2("lake2.vga"), lake3("lake3.vga"), xeen1("xeen1.vga"); + _subtitles.load("special.bin"); // Show the production splash screen sound.playSong("mm4theme.m"); @@ -207,23 +208,121 @@ bool CloudsCutscenes::showCloudsIntro() { lake3.clear(); xeen1.clear(); - // - const char *const VOCS[14] = { - "crodo1.voc", "crodo2.voc", "iamking.voc", "crodo3.voc", - "ya1.voc", "crodo4a.voc", "crodo4b.voc", "crodo4c.voc", - "xeenlaff.voc", "tiger2&.voc", "crodo5.voc", "crodo6.voc", - "xeenlaff.voc", "tiger2&.voc" - }; - SpriteResource groupo("groupo.vga"), group("group.vga"), crodo("crodo.vga"); + // All the lines whilst the scroll is open + SpriteResource groupo("groupo.vga"), group("group.vga"), + crodo("crodo.vga"), box("box.vga"); groupo.draw(screen, 0); groupo.draw(screen, 1, Common::Point(160, 0)); crodo.draw(screen, 0, Common::Point(0, -5)); screen._windows[0].writeString(CLOUDS_INTRO1); + + doScroll(false, true); + sound.setMusicVolume(75); + screen.restoreBackground(); + screen.update(); + resetSubtitles(0, 1); - // TODO + // Loop through each spoken line + int ctr1 = 0, ctr2 = 0, ctr3 = 0, ctr4 = 0, ctr5 = 0, totalCtr = 0; + for (int lineCtr = 0; lineCtr < 14; ++lineCtr) { + if (lineCtr != 6 || lineCtr != 7) { + sound.playSound(_INTRO_VOCS[lineCtr]); + } + + for (int frameNum = 0, lookup = 0; sound.isPlaying() || _subtitleSize; ) { + groupo.draw(screen, 0); + groupo.draw(screen, 1, Common::Point(160, 0)); + + switch (lineCtr) { + case 2: + ctr1 = (ctr1 + 1) % 5; + group.draw(screen, ctr1); + ctr4 = (ctr4 + 1) % 9; + break; + + case 4: + ctr4 = (ctr4 + 1) % 9 + 9; + break; + + case 8: + case 12: + ctr2 = (ctr2 + 1) % 3; + ctr4 = (ctr4 + 1) % 9; + ctr3 = (ctr3 + 1) % 6 + 3; + break; + + case 9: + case 13: + ctr3 = (ctr3 + 1) % 3; + group.draw(screen, ctr3 + 43, Common::Point(178, 134)); + ctr4 = (ctr4 + 1) % 9; + ctr2 = (ctr2 % 15) + 3; + break; + + default: + ctr4 = (ctr4 + 1) % 9; + ctr2 = (ctr2 + 1) % 15 + 3; + ctr3 = (ctr3 + 1) % 6 + 3; + break; + } + + group.draw(screen, ctr4 + 5, Common::Point(0, 99)); + group.draw(screen, ctr2 + 24, Common::Point(202, 12)); + if ((++totalCtr % 30) == 0) + group.draw(screen, 43, Common::Point(178, 134)); + + switch (lineCtr) { + case 2: + case 4: + case 8: + case 9: + case 12: + case 13: { + crodo.draw(screen, 0, Common::Point(0, -5)); + screen._windows[0].writeString(CLOUDS_INTRO1); + + ctr5 = (ctr5 + 1) % 19; + WAIT(1); + showSubtitles(); + continue; + } + + default: + crodo.draw(screen, frameNum, Common::Point(0, -5)); + if (lookup > 30) + lookup = 30; + frameNum = _INTRO_FRAMES_VALS[_INTRO_FRAMES_LOOKUP[lineCtr]][lookup]; + screen._windows[0].writeString(CLOUDS_INTRO1); + + ctr5 = (ctr5 + 1) % 19; + WAIT(1); + showSubtitles(); + break; + } + + events.updateGameCounter(); + while (events.timeElapsed() < _INTRO_FRAMES_MAX[_INTRO_FRAMES_LOOKUP[lineCtr]][lookup] + || sound.isPlaying()) { + WAIT(1); + } + + if (!sound._soundOn && lookup > 30) + lookup = 0; + } + + if (!sound._soundOn) + lineCtr = 20; + + if (lineCtr == 5) + sound.playSound(_INTRO_VOCS[6]); + else if (lineCtr == 6) + sound.playSound(_INTRO_VOCS[7]); + } + + sound.songCommand(50); + doScroll(true, false); - events.wait(5000); return true; } @@ -232,4 +331,67 @@ bool CloudsCutscenes::showCloudsEnding() { return true; } +const char *const CloudsCutscenes::_INTRO_VOCS[14] = { + "crodo1.voc", "crodo2.voc", "iamking.voc", "crodo3.voc", + "ya1.voc", "crodo4a.voc", "crodo4b.voc", "crodo4c.voc", + "xeenlaff.voc", "tiger2&.voc", "crodo5.voc", "crodo6.voc", + "xeenlaff.voc", "tiger2&.voc" +}; +const int CloudsCutscenes::_INTRO_FRAMES_LOOKUP[14] = { 0, 1, 0, 2, 0, 3, 4, 5, 0, 0, 6, 7, 0, 0 }; +const int CloudsCutscenes::_INTRO_FRAMES_VALS[8][32] = { + { + 4, 2, 3, 0, 2, 3, 2, 0, 1, 1, 3, 4, 3, 2, 4, 2, + 3, 4, 3, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + },{ + 3, 2, 3, 2, 4, 3, 0, 3, 2, 2, 3, 1, 2, 3, 3, 3, + 2, 3, 2, 3, 2, 0, 3, 2, 0, 0, 0, 0, 0, 0, 2, 4 + },{ + 3, 1, 2, 3, 0, 3, 4, 3, 2, 3, 0, 3, 2, 3, 2, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3 + },{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 3 + },{ + 4, 2, 2, 3, 2, 3, 3, 4, 2, 4, 2, 0, 3, 2, 3, 2, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 2, 3 + },{ + 2, 0, 2, 3, 2, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 2, 3, 1 + },{ + 3, 2, 0, 2, 4, 2, 3, 2, 3, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 3, 4, 0, 2 + },{ + 3, 2, 4, 1, 2, 4, 3, 2, 3, 0, 2, 2, 0, 3, 2, 3, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +const int CloudsCutscenes::_INTRO_FRAMES_MAX[8][32] = { + { + 2, 5, 6, 9, 10, 11, 12, 13, 14, 23, 25, 29, 31, 35, 38, 41, + 42, 45, 50, 52, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, { + 1, 4, 6, 8, 9, 11, 13, 15, 17, 18, 19, 22, 28, 29, 30, 31, + 0, 39, 0, 44, 0, 50, 51, 0, 54, 0, 0, 0, 0, 0, 0, 4 + }, { + 6, 9, 11, 13, 15, 19, 21, 23, 25, 27, 28, 31, 35, 39, 40, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 7 + }, { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4 + }, { + 5, 9, 10, 11, 13, 15, 18, 23, 26, 31, 33, 36, 37, 41, 43, 45, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 12 + }, { + 14, 17, 20, 23, 27, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 8, 11, 13 + }, { + 15, 16, 17, 19, 21, 24, 24, 27, 34, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 10, 11, 13 + }, { + 17, 19, 22, 23, 26, 30, 32, 34, 40, 43, 47, 52, 53, 55, 57, 60, + 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + } // End of namespace Xeen diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.h b/engines/xeen/worldofxeen/clouds_cutscenes.h index 1440458c10..5bc9595239 100644 --- a/engines/xeen/worldofxeen/clouds_cutscenes.h +++ b/engines/xeen/worldofxeen/clouds_cutscenes.h @@ -29,6 +29,11 @@ namespace Xeen { class CloudsCutscenes : public Cutscenes { +private: + static const char *const _INTRO_VOCS[14]; + static const int _INTRO_FRAMES_LOOKUP[14]; + static const int _INTRO_FRAMES_VALS[8][32]; + static const int _INTRO_FRAMES_MAX[8][32]; public: CloudsCutscenes(XeenEngine *vm) : Cutscenes(vm) {} -- cgit v1.2.3