diff options
author | Paul Gilbert | 2016-09-18 17:31:12 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-09-18 17:31:12 -0400 |
commit | 383cc850b99cc7b2ed30e9fde9bbf77a128f0e6d (patch) | |
tree | b198ddf516e8bec909a9962374fc6690cd8e3662 | |
parent | 61d8ec8b7fae1bcd28084ddebf28ade67de3e20f (diff) | |
download | scummvm-rg350-383cc850b99cc7b2ed30e9fde9bbf77a128f0e6d.tar.gz scummvm-rg350-383cc850b99cc7b2ed30e9fde9bbf77a128f0e6d.tar.bz2 scummvm-rg350-383cc850b99cc7b2ed30e9fde9bbf77a128f0e6d.zip |
XEEN: Beginnings of Darkside endgame, subtitle code
25 files changed, 292 insertions, 47 deletions
diff --git a/engines/xeen/dialogs_error.cpp b/engines/xeen/dialogs_error.cpp index 0a8f5923f2..0cad2eb418 100644 --- a/engines/xeen/dialogs_error.cpp +++ b/engines/xeen/dialogs_error.cpp @@ -60,7 +60,7 @@ void ErrorDialog::execute(const Common::String &msg, ErrorWaitType waitType) { events.updateGameCounter(); _vm->_interface->draw3d(true); - events.wait(1, true); + events.wait(1); if (checkEvents(_vm)) break; } while (!_vm->shouldQuit() && !_buttonValue); diff --git a/engines/xeen/dialogs_info.cpp b/engines/xeen/dialogs_info.cpp index 56755630da..f475d38429 100644 --- a/engines/xeen/dialogs_info.cpp +++ b/engines/xeen/dialogs_info.cpp @@ -72,7 +72,7 @@ void InfoDialog::execute() { w.writeString(details); w.update(); - events.wait(1, true); + events.wait(1); } while (!_vm->shouldQuit() && !events.isKeyMousePressed()); events.clearEvents(); diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp index 50d6ed2eca..943b038d09 100644 --- a/engines/xeen/dialogs_input.cpp +++ b/engines/xeen/dialogs_input.cpp @@ -97,7 +97,7 @@ Common::KeyCode Input::doCursor(const Common::String &msg) { if (flag) screen._windows[3].update(); - events.wait(1, true); + events.wait(1); if (events.isKeyPending()) { Common::KeyState keyState; events.getKey(keyState); @@ -233,7 +233,7 @@ int Choose123::execute(int numOptions) { delay = 1; } - events.wait(delay, true); + events.wait(delay); if (_vm->shouldQuit()) return 0; } while (!_buttonValue); diff --git a/engines/xeen/dialogs_options.cpp b/engines/xeen/dialogs_options.cpp index b2390e344f..88ee6d33d3 100644 --- a/engines/xeen/dialogs_options.cpp +++ b/engines/xeen/dialogs_options.cpp @@ -114,7 +114,7 @@ void OptionsMenu::showTitles1(SpriteResource &sprites) { screen.restoreBackground(); sprites.draw(screen, frameNum); - events.wait(4, true); + events.wait(4); } } diff --git a/engines/xeen/dialogs_party.cpp b/engines/xeen/dialogs_party.cpp index ac5c749d03..88e0b17547 100644 --- a/engines/xeen/dialogs_party.cpp +++ b/engines/xeen/dialogs_party.cpp @@ -887,7 +887,7 @@ void PartyDialog::drawDice(SpriteResource &dice) { w.update(); // Wait for keypress - events.wait(1, true); + events.wait(1); checkEvents(_vm); } diff --git a/engines/xeen/dialogs_query.cpp b/engines/xeen/dialogs_query.cpp index abaddafe69..d8dfea116a 100644 --- a/engines/xeen/dialogs_query.cpp +++ b/engines/xeen/dialogs_query.cpp @@ -136,7 +136,7 @@ bool YesNo::execute(bool type, bool townFlag) { //numFrames = 1; } - events.wait(3, true); + events.wait(3); checkEvents(_vm); if (!_buttonValue) continue; diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp index 77d1b4ef6e..9a9d39a40a 100644 --- a/engines/xeen/dialogs_spells.cpp +++ b/engines/xeen/dialogs_spells.cpp @@ -1019,7 +1019,7 @@ void IdentifyMonster::execute() { w.frame(); screen._windows[3].update(); - events.wait(1); + events.wait(1, false); } while (!events.isKeyMousePressed()); w.close(); diff --git a/engines/xeen/dialogs_whowill.cpp b/engines/xeen/dialogs_whowill.cpp index fd72154cba..d33b302a60 100644 --- a/engines/xeen/dialogs_whowill.cpp +++ b/engines/xeen/dialogs_whowill.cpp @@ -76,7 +76,7 @@ int WhoWill::execute(int message, int action, bool type) { numFrames = 1; } - events.wait(numFrames, true); + events.wait(numFrames); checkEvents(_vm); if (!_buttonValue) continue; diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp index b928677aac..9c829a1a7b 100644 --- a/engines/xeen/files.cpp +++ b/engines/xeen/files.cpp @@ -267,4 +267,13 @@ Common::String File::readString() { return result; } +/*------------------------------------------------------------------------*/ + +void StringArray::load(const Common::String &name) { + File f(name); + clear(); + while (f.pos() < f.size()) + push_back(f.readString()); +} + } // End of namespace Xeen diff --git a/engines/xeen/files.h b/engines/xeen/files.h index fa595976f4..ae97d65c61 100644 --- a/engines/xeen/files.h +++ b/engines/xeen/files.h @@ -27,6 +27,7 @@ #include "common/array.h" #include "common/file.h" #include "common/serializer.h" +#include "common/str-array.h" #include "graphics/surface.h" namespace Xeen { @@ -111,6 +112,17 @@ public: Common::String readString(); }; +class StringArray : public Common::StringArray { +public: + StringArray() {} + StringArray(const Common::String &name) { load(name); } + + /** + * Loads a string array from the specified file + */ + void load(const Common::String &name); +}; + class XeenSerializer : public Common::Serializer { private: Common::SeekableReadStream *_in; diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index bdb871bb6e..2516c1b851 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -1300,7 +1300,7 @@ void Interface::draw3d(bool updateFlag, bool skipDelay) { } if (!skipDelay) - events.wait(2); + events.wait(2, false); } void Interface::handleFalling() { @@ -2274,7 +2274,7 @@ void Interface::spellFX(Character *c) { draw3d(false); screen._windows[0].update(); - events.wait(screen._windows[11]._enabled ? 2 : 1); + events.wait(screen._windows[11]._enabled ? 2 : 1,false); } drawParty(true); diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index 7435790335..833b8cf1d2 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -1,6 +1,7 @@ MODULE := engines/xeen MODULE_OBJS := \ + worldofxeen/cutscenes.o \ worldofxeen/clouds_cutscenes.o \ worldofxeen/darkside_cutscenes.o \ worldofxeen/worldofxeen.o \ diff --git a/engines/xeen/music.cpp b/engines/xeen/music.cpp index ba6ba17c5e..9dab94b5cb 100644 --- a/engines/xeen/music.cpp +++ b/engines/xeen/music.cpp @@ -656,7 +656,7 @@ const uint AdlibMusicDriver::WAVEFORMS[24] = { /*------------------------------------------------------------------------*/ Music::Music() : _musicDriver(nullptr), _songData(nullptr), - _archiveType(ANY_ARCHIVE), _effectsData(nullptr) { + _archiveType(ANY_ARCHIVE), _effectsData(nullptr), _musicOn(true) { _musicDriver = new AdlibMusicDriver(); } diff --git a/engines/xeen/music.h b/engines/xeen/music.h index d675a37d08..bf77398885 100644 --- a/engines/xeen/music.h +++ b/engines/xeen/music.h @@ -316,7 +316,8 @@ private: * Updates any playing music */ void update(); -protected: +public: + bool _musicOn; public: Music(); ~Music(); diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 64b387499d..41dd17d80a 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -230,7 +230,7 @@ int Scripts::checkEvents() { do { intf.draw3d(true); events.updateGameCounter(); - events.wait(1, true); + events.wait(1); } while (!events.isKeyMousePressed()); events.clearEvents(); @@ -1759,7 +1759,7 @@ void Scripts::display(bool justifyFlag, int var46) { events.updateGameCounter(); intf.draw3d(true); - events.wait(1, true); + events.wait(1); } while (!_vm->shouldQuit() && !events.isKeyMousePressed()); w.writeString(justifyFlag ? "\r" : "\r\x3""c"); diff --git a/engines/xeen/sound.cpp b/engines/xeen/sound.cpp index 3896fec155..d53f197cac 100644 --- a/engines/xeen/sound.cpp +++ b/engines/xeen/sound.cpp @@ -29,7 +29,8 @@ namespace Xeen { /*------------------------------------------------------------------------*/ -Sound::Sound(XeenEngine *vm, Audio::Mixer *mixer): Music(), _mixer(mixer) { +Sound::Sound(XeenEngine *vm, Audio::Mixer *mixer): Music(), + _mixer(mixer), _soundOn(true) { } Sound::~Sound() { diff --git a/engines/xeen/sound.h b/engines/xeen/sound.h index c45d4e4b95..41342dfab1 100644 --- a/engines/xeen/sound.h +++ b/engines/xeen/sound.h @@ -37,6 +37,8 @@ private: Audio::Mixer *_mixer; Audio::SoundHandle _soundHandle; public: + bool _soundOn; +public: Sound(XeenEngine *vm, Audio::Mixer *mixer); virtual ~Sound(); diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp index 1a0761ae40..1fc3ee1f57 100644 --- a/engines/xeen/spells.cpp +++ b/engines/xeen/spells.cpp @@ -467,7 +467,7 @@ void Spells::detectMonster() { events.updateGameCounter(); intf.draw3d(true); - events.wait(1); + events.wait(1, false); } while (!events.isKeyMousePressed()); w.close(); diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp index 795d4cddd6..1947129c57 100644 --- a/engines/xeen/town.cpp +++ b/engines/xeen/town.cpp @@ -1248,7 +1248,7 @@ bool TownMessage::execute(int portrait, const Common::String &name, const Common clearButtons(); do { - events.wait(3, true); + events.wait(3); checkEvents(_vm); if (_vm->shouldQuit()) return false; diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.h b/engines/xeen/worldofxeen/clouds_cutscenes.h index 2c2ed602ea..ff935a75fe 100644 --- a/engines/xeen/worldofxeen/clouds_cutscenes.h +++ b/engines/xeen/worldofxeen/clouds_cutscenes.h @@ -23,17 +23,14 @@ #ifndef XEEN_WORLDOFXEEN_CLOUDS_CUTSCENES_H #define XEEN_WORLDOFXEEN_CLOUDS_CUTSCENES_H +#include "xeen/worldofxeen/cutscenes.h" #include "xeen/xeen.h" namespace Xeen { -class XeenEngine; - -class CloudsCutscenes { -private: - XeenEngine *_vm; +class CloudsCutscenes : public Cutscenes { public: - CloudsCutscenes(XeenEngine *vm) : _vm(vm) {} + CloudsCutscenes(XeenEngine *vm) : Cutscenes(vm) {} /** * Shows the Clouds of Xeen title screen diff --git a/engines/xeen/worldofxeen/cutscenes.cpp b/engines/xeen/worldofxeen/cutscenes.cpp new file mode 100644 index 0000000000..20b4158c32 --- /dev/null +++ b/engines/xeen/worldofxeen/cutscenes.cpp @@ -0,0 +1,100 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "xeen/worldofxeen/cutscenes.h" +#include "xeen/xeen.h" + +namespace Xeen { + +static const char *SUBTITLE_LINE = "\xC" "35\x3" "c\xB" "190\x9" "000%s"; + +void Cutscenes::resetSubtitles() { + _subtitleLineNum = _subtitleSize = 0; +} + +void Cutscenes::showSubtitles(uint windowIndex) { + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + + if (sound._soundOn) { + // Sound is on, so subtitles aren't needed + resetSubtitles(); + } else { + if (timeElapsed() > 1) { + ++_subtitleSize; + const Common::String &line = _subtitles[_subtitleLineNum]; + Common::String lineStr(line.c_str(), line.c_str() + _subtitleSize); + _subtitleLine = Common::String::format(SUBTITLE_LINE, lineStr.c_str()); + + // If displayed a full line, then move to the next line + if (_subtitleSize == line.size()) { + _subtitleSize = 0; + if (++_subtitleLineNum == _subtitles.size()) + _subtitleLineNum = 0; + } + } + + // Draw the box sprite + if (!_boxSprites) + // Not already loaded, so load it + _boxSprites = new SpriteResource("box.vga"); + _boxSprites->draw(screen, 0, Common::Point(36, 189)); + + // Write the subtitle line + screen._windows[windowIndex].writeString(_subtitleLine); + } + + screen.update(); +} + +void Cutscenes::freeSubtitles() { + delete _boxSprites; + _boxSprites = nullptr; + _subtitles.clear(); +} + +bool Cutscenes::subtitlesWait(uint minTime) { + EventsManager &events = *_vm->_events; + + events.updateGameCounter(); + recordTime(); + while (events.timeElapsed() < minTime || _subtitleSize != 0) { + events.pollEventsAndWait(); + if (events.isKeyMousePressed()) + return false; + + showSubtitles(); + } + + return true; +} + +void Cutscenes::recordTime() { + _vm->_events->timeMark1(); +} + +uint Cutscenes::timeElapsed() { + return _vm->_events->timeElapsed1(); +} + + +} // End of namespace Xeen diff --git a/engines/xeen/worldofxeen/cutscenes.h b/engines/xeen/worldofxeen/cutscenes.h new file mode 100644 index 0000000000..895094d3dd --- /dev/null +++ b/engines/xeen/worldofxeen/cutscenes.h @@ -0,0 +1,79 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_WORLDOFXEEN_CUTSCENES_H +#define XEEN_WORLDOFXEEN_CUTSCENES_H + +#include "xeen/files.h" +#include "xeen/sprites.h" + +namespace Xeen { + +class XeenEngine; + +class Cutscenes { +protected: + XeenEngine *_vm; + StringArray _subtitles; + SpriteResource *_boxSprites; + uint _timeElapsed; + Common::String _subtitleLine; + uint _subtitleLineNum, _subtitleSize; +protected: + Cutscenes(XeenEngine *vm) : _vm(vm), _timeElapsed(0), _boxSprites(nullptr), + _subtitleLineNum(0), _subtitleSize(0) {} + + /** + * Resets the subtitles position + */ + void resetSubtitles(); + + /** + * Free subtitles + */ + void freeSubtitles(); + + /** + * Shows subtitles + */ + void showSubtitles(uint windowIndex = 0); + + /** + * Delays either the specified number of frames, or until + * an entire subtitle line is shown if subtitles are on + */ + bool subtitlesWait(uint minTime); + + /** + * Records the current execution time + */ + void recordTime(); + + /** + * Returns the number of ticks since the last recordTime + */ + uint timeElapsed(); +}; + +} // End of namespace Xeen + +#endif /* XEEN_WORLDOFXEEN_CUTSCENES_H */ diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.cpp b/engines/xeen/worldofxeen/darkside_cutscenes.cpp index a30f354d67..0c806dec41 100644 --- a/engines/xeen/worldofxeen/darkside_cutscenes.cpp +++ b/engines/xeen/worldofxeen/darkside_cutscenes.cpp @@ -81,7 +81,7 @@ bool DarkSideCutscenes::showDarkSideTitle() { ++nwcFrame; } - if (events.wait(2, true)) + if (events.wait(2)) return false; } @@ -112,14 +112,14 @@ bool DarkSideCutscenes::showDarkSideTitle() { break; } - if (events.wait(2, true)) + if (events.wait(2)) return false; } if (_vm->shouldQuit()) return false; // Pause for a bit - if (events.wait(10, true)) + if (events.wait(10)) return false; sound.setMusicVolume(95); @@ -130,7 +130,7 @@ bool DarkSideCutscenes::showDarkSideTitle() { screen.fadeIn(4); events.updateGameCounter(); - events.wait(60, true); + events.wait(60); return true; } @@ -149,6 +149,7 @@ bool DarkSideCutscenes::showDarkSideIntro() { }; screen.fadeOut(8); + screen.loadPalette("dark.pal"); screen.loadBackground("pyramid2.raw"); screen.loadPage(0); screen.loadPage(1); @@ -158,14 +159,14 @@ bool DarkSideCutscenes::showDarkSideIntro() { SpriteResource sprites[3] = { SpriteResource("title.int"), SpriteResource("pyratop.int"), SpriteResource("pyramid.int") }; - File voc[2]; - voc[0].open("pharoh1a.voc"); - voc[1].open("pharoh1b.voc"); screen.vertMerge(SCREEN_HEIGHT); screen.loadPage(0); screen.loadPage(1); + // Play the intro music + sound.playSong("bigtheme.m"); + // Show Might and Magic Darkside of Xeen title, and gradualy scroll // the background vertically down to show the Pharoah's base int yp = 0; @@ -196,7 +197,7 @@ bool DarkSideCutscenes::showDarkSideIntro() { yCtr -= timeExpired; yp = MIN((uint)(yp + timeExpired), (uint)200); - if (events.wait(1, true)) + if (events.wait(1)) return false; if (fadeFlag) { @@ -211,7 +212,8 @@ bool DarkSideCutscenes::showDarkSideIntro() { screen.freePages(); events.updateGameCounter(); - events.wait(30, true); + if (events.wait(30)) + return false; // Zoom into the Pharoah's base closeup view for (int idx = 14; idx >= 0; --idx) { @@ -222,36 +224,74 @@ bool DarkSideCutscenes::showDarkSideIntro() { if (idx == 2) sound.setMusicVolume(48); - if (events.wait(2, true)) + if (events.wait(2)) return false; } - // TODO: More - sound.playSong(voc[0]); - sound.playSong(voc[1]); - return true; } bool DarkSideCutscenes::showDarkSideEnding() { EventsManager &events = *_vm->_events; Screen &screen = *_vm->_screen; -// Sound &sound = *_vm->_sound; + Sound &sound = *_vm->_sound; - //Voc voc("ido2.voc"); - // Music newBright("newbrigh.m"); + File ido2("ido2.voc"); SpriteResource box("box.vga"); -// newBright.play(); + sound.playSong("dngon3.m"); screen.loadBackground("scene1.raw"); screen.loadPalette("endgame.pal"); screen.update(); screen.fadeIn(4); events.updateGameCounter(); + if (events.wait(30)) + return false; + + screen.loadBackground("scene2-b.raw"); + screen.update(); + screen.saveBackground(); + + SpriteResource faceEnd("face.end"); + events.updateGameCounter(); + screen.restoreBackground(); + faceEnd.draw(screen, 0, Common::Point(29, 76), SPRFLAG_4000); + screen.update(); + + screen.fadeIn(4); + if (events.wait(1, false)) + return false; + + _subtitles.load("special.bin"); + recordTime(); + resetSubtitles(); + + // Alamar stands up + for (int idx = 74; idx > 20; idx -= 2) { + if (idx == 60) + sound.songCommand(207); + else if (idx == 22) + sound.stopSong(); + + events.updateGameCounter(); + screen.restoreBackground(); + faceEnd.draw(screen, 0, Common::Point(29, idx), SPRFLAG_4000); + screen.update(); - // TODO + if (events.wait(2)) + return false; + } + + // Alamar says "Come to me" + sound.playSound("come2.voc"); + if (!subtitlesWait(27)) + return false; + + // TODO events.wait(5000); + + freeSubtitles(); return true; } diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.h b/engines/xeen/worldofxeen/darkside_cutscenes.h index 1b78e3ea2d..567b70e05f 100644 --- a/engines/xeen/worldofxeen/darkside_cutscenes.h +++ b/engines/xeen/worldofxeen/darkside_cutscenes.h @@ -23,15 +23,15 @@ #ifndef XEEN_WORLDOFXEEN_DARKSIDE_CUTSCENES_H #define XEEN_WORLDOFXEEN_DARKSIDE_CUTSCENES_H +#include "xeen/worldofxeen/cutscenes.h" + namespace Xeen { class XeenEngine; -class DarkSideCutscenes { -private: - XeenEngine *_vm; +class DarkSideCutscenes : public Cutscenes { public: - DarkSideCutscenes(XeenEngine *vm) : _vm(vm) {} + DarkSideCutscenes(XeenEngine *vm) : Cutscenes(vm) {} /** * Shows the Dark Side of Xeen title screen diff --git a/engines/xeen/worldofxeen/worldofxeen.cpp b/engines/xeen/worldofxeen/worldofxeen.cpp index a71efbb162..ccdbf8cf3b 100644 --- a/engines/xeen/worldofxeen/worldofxeen.cpp +++ b/engines/xeen/worldofxeen/worldofxeen.cpp @@ -40,9 +40,12 @@ void WorldOfXeenEngine::showIntro() { if (gDebugLevel == 0) return; + showDarkSideEnding(); + /* bool completed = showDarkSideTitle(); if (!_seenDarkSideIntro && completed) showDarkSideIntro(); + */ } } // End of namespace Xeen |