From 76142e2e7dddcc41906bdddc1138d452b15de3bc Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Mon, 17 Jun 2019 21:02:59 +0200 Subject: SUPERNOVA2: Add outro --- engines/supernova2/ms2_def.h | 2 +- engines/supernova2/rooms.cpp | 79 ++++++++++++++++++++++++++++++++++++++- engines/supernova2/rooms.h | 3 ++ engines/supernova2/screen.cpp | 25 +++++++++---- engines/supernova2/screen.h | 5 ++- engines/supernova2/sound.cpp | 8 ++++ engines/supernova2/sound.h | 2 + engines/supernova2/state.cpp | 2 + engines/supernova2/supernova2.cpp | 4 +- engines/supernova2/supernova2.h | 2 +- 10 files changed, 117 insertions(+), 15 deletions(-) diff --git a/engines/supernova2/ms2_def.h b/engines/supernova2/ms2_def.h index b36ae7f517..84f5cdde3a 100644 --- a/engines/supernova2/ms2_def.h +++ b/engines/supernova2/ms2_def.h @@ -136,7 +136,7 @@ kString30, kString31, kStringGenericInteract1, kStringGenericInteract2, kStringG kStringGenericInteract4, kStringGenericInteract5, kStringGenericInteract6, kStringGenericInteract7, kStringGenericInteract8, kStringGenericInteract9, kStringGenericInteract10, kStringGenericInteract11, kStringGenericInteract12, kStringGenericInteract13, kStringIntro1, kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, -kString50, kString51, kString52, kString53, kString54, +kStringOutro1, kStringOutro2, kStringOutro3, kStringOutro4, kStringOutro5, kStringShout1, kStringShout2, kStringShout3, kStringShout4, kStringShout5, kStringShout6, kStringShout7, kStringShout8, kStringShout9, kStringShout10, kStringShout11, kStringShout12, kStringShout13, kStringShout14, kStringShout15, diff --git a/engines/supernova2/rooms.cpp b/engines/supernova2/rooms.cpp index 9213f0d0da..2e594287ce 100644 --- a/engines/supernova2/rooms.cpp +++ b/engines/supernova2/rooms.cpp @@ -2044,6 +2044,30 @@ Ship::Ship(Supernova2Engine *vm, GameManager *gm) { _objectState[4] = Object(_id, kStringSpaceSuit, kStringSpaceSuitDescription, SUIT, TAKE, 255, 255, 1); _objectState[5] = Object(_id, kStringCable, kStringCableDescription1, RCABLE, COMBINABLE, 255, 255, 0); _objectState[6] = Object(_id, kStringCable, kStringCableDescription2, CABLE, TAKE | COMBINABLE, 255, 255, 8 + 128); + + _outroText = + _vm->getGameString(kStringIntro1) + '\0' + + _vm->getGameString(kStringIntro2) + '\0' + + _vm->getGameString(kStringIntro3) + '\0' + + _vm->getGameString(kStringIntro4) + '\0' + + _vm->getGameString(kStringIntro5) + '\0' + + "^Matthias Neef#" + '\0' + + "^Sascha Otterbach#" + '\0' + + "^Thomas Mazzoni#" + '\0' + + "^Matthias Klein#" + '\0' + + "^Gerrit Rothmaier#" + '\0' + + "^Thomas Hassler#" + '\0' + + "^Rene Kach#" + '\0' + + '\233' + '\0'; + Common::String waitString = "##################"; + _outroText2 = + waitString + '\0' + + _vm->getGameString(kStringOutro1) + '\0' + + _vm->getGameString(kStringOutro2) + '\0' + + _vm->getGameString(kStringOutro3) + '\0' + + _vm->getGameString(kStringOutro4) + '\0' + + _vm->getGameString(kStringOutro5) + '\0' + + '\233' + '\0'; } void Ship::onEntrance() { @@ -2194,13 +2218,64 @@ bool Ship::interact(Action verb, Object &obj1, Object &obj2) { _vm->renderImage(12); _gm->wait(18); // TODO some palette stuff - _vm->renderImage(13); - _vm->playSound(kMusicMadMonkeys); + outro(); } else return false; return true; } +void Ship::outro() { + _vm->_screen->paletteFadeOut(100); + _vm->renderImage(13); + // Because the screen is partialy faded out, the original values (63, 20, 20) + // should be multiplied by 2.55, but are multiplied by 3.5, because the color + // looks closer to the original + byte palette[768]; + _vm->_system->getPaletteManager()->grabPalette(palette, 0, 255); + palette[282] = 220; + palette[283] = 70; + palette[284] = 70; + // Restore marquee colors + for (int i = 0; i < 3; i++) { + palette[kColorPurple * 3 + i] *= 2.5; + palette[kColorLightYellow * 3 + i] *= 2.5; + } + _vm->_system->getPaletteManager()->setPalette(palette, 0, 255); + _vm->playSound(kMusicMadMonkeys); + _vm->renderBox(0, 190, 320, 10, kColorBlack); + Marquee marquee(_vm->_screen, Marquee::kMarqueeOutro, _outroText.c_str()); + for(int i = 0; i < 2; i++) { + while (!_vm->shouldQuit()) { + _gm->updateEvents(); + + if (!marquee.renderCharacter() || _gm->_mouseClicked || _gm->_keyPressed) + break; + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + marquee.reset(); + } + Marquee marquee2(_vm->_screen, Marquee::kMarqueeOutro, _outroText2.c_str()); + while (!_vm->shouldQuit()) { + _gm->updateEvents(); + + if (!marquee2.renderCharacter() || _gm->_mouseClicked || _gm->_keyPressed) + break; + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + // TODO: End with some end of music + int volume; + do { + volume = _vm->_sound->getVolume() - 10; + _vm->_sound->setVolume(volume); + _gm->waitOnInput(1); + } while (volume > 10 && !_vm->shouldQuit()); + Common::Event event; + event.type = Common::EVENT_RTL; + _vm->getEventManager()->pushEvent(event); +} + void Ship::kill() { _vm->playSound(kAudioShipDeath); while (_vm->_sound->isPlaying() && !_vm->shouldQuit()) diff --git a/engines/supernova2/rooms.h b/engines/supernova2/rooms.h index 3d1d066362..aee27646f6 100644 --- a/engines/supernova2/rooms.h +++ b/engines/supernova2/rooms.h @@ -228,9 +228,12 @@ public: virtual void onEntrance(); virtual void animation(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + Common::String _outroText; + Common::String _outroText2; private: void kill(); + void outro(); }; class Pyramid : public Room { diff --git a/engines/supernova2/screen.cpp b/engines/supernova2/screen.cpp index 91ec4051ac..82e38af091 100644 --- a/engines/supernova2/screen.cpp +++ b/engines/supernova2/screen.cpp @@ -111,7 +111,7 @@ Marquee::Marquee(Screen *screen, MarqueeId id, const char *text) _y = 191; _loop = true; } else if (id == kMarqueeOutro) { - _y = 1; + _y = 191; } _textWidth = Screen::textWidth(_text); @@ -125,10 +125,18 @@ void Marquee::clearText() { _screen->renderBox(_x, _y - 1, _textWidth + 1, 9, kColorBlack); } -void Marquee::renderCharacter() { +void Marquee::reset() { + _text = _textBegin; + clearText(); + _textWidth = Screen::textWidth(_text); + _x = kScreenWidth / 2 - _textWidth / 2; + _screen->_textCursorX = _x; +} + +bool Marquee::renderCharacter() { if (_delay != 0) { _delay--; - return; + return true; } switch (*_text) { @@ -141,6 +149,8 @@ void Marquee::renderCharacter() { _x = kScreenWidth / 2 - _textWidth / 2; _screen->_textCursorX = _x; } + else + return false; break; case '\0': clearText(); @@ -165,6 +175,7 @@ void Marquee::renderCharacter() { _delay = 1; break; } + return true; } Screen::Screen(Supernova2Engine *vm, ResourceManager *resMan) @@ -591,8 +602,8 @@ void Screen::paletteBrightness() { _vm->_system->getPaletteManager()->setPalette(palette, 0, 255); } -void Screen::paletteFadeOut() { - while (_guiBrightness > 10) { +void Screen::paletteFadeOut(int minBrightness) { + while (_guiBrightness > minBrightness + 10) { _guiBrightness -= 10; if (_viewportBrightness > _guiBrightness) _viewportBrightness = _guiBrightness; @@ -600,8 +611,8 @@ void Screen::paletteFadeOut() { _vm->_system->updateScreen(); _vm->_system->delayMillis(_vm->_delay); } - _guiBrightness = 0; - _viewportBrightness = 0; + _guiBrightness = minBrightness; + _viewportBrightness = minBrightness; paletteBrightness(); _vm->_system->updateScreen(); } diff --git a/engines/supernova2/screen.h b/engines/supernova2/screen.h index 584ff9b440..b5c3388017 100644 --- a/engines/supernova2/screen.h +++ b/engines/supernova2/screen.h @@ -102,7 +102,8 @@ public: Marquee(Screen *screen, MarqueeId id, const char *text); - void renderCharacter(); + bool renderCharacter(); + void reset(); private: void clearText(); @@ -145,7 +146,7 @@ public: const ImageInfo *getImageInfo(ImageId id) const; bool isMessageShown() const; void paletteFadeIn(int maxViewportBrightness); - void paletteFadeOut(); + void paletteFadeOut(int minBrightness); void paletteBrightness(); void renderImage(ImageId id, bool removeImage = false); void renderImage(int section); diff --git a/engines/supernova2/sound.cpp b/engines/supernova2/sound.cpp index c0688acd45..d16873d031 100644 --- a/engines/supernova2/sound.cpp +++ b/engines/supernova2/sound.cpp @@ -70,4 +70,12 @@ void Sound::stop() { _mixer->stopHandle(_soundHandle); } +int Sound::getVolume() { + return _mixer->getChannelVolume(_soundHandle); +} + +void Sound::setVolume(int volume) { + _mixer->setChannelVolume(_soundHandle, volume); +} + } diff --git a/engines/supernova2/sound.h b/engines/supernova2/sound.h index 17555c475f..4b8f1b94c2 100644 --- a/engines/supernova2/sound.h +++ b/engines/supernova2/sound.h @@ -68,6 +68,8 @@ public: void play(AudioId index); void play(MusicId index); void playSiren(); + void setVolume(int volume); + int getVolume(); void stop(); bool isPlaying(); private: diff --git a/engines/supernova2/state.cpp b/engines/supernova2/state.cpp index 1652170e9e..ab4c4b8ec8 100644 --- a/engines/supernova2/state.cpp +++ b/engines/supernova2/state.cpp @@ -132,6 +132,8 @@ bool GameManager::deserialize(Common::ReadStream *in, int version) { for (int i = 0; i < NUMROOMS; ++i) { _rooms[i]->deserialize(in, version); } + delete _rooms[SHIP]; + _rooms[SHIP] = new Ship(_vm, this); _lastRoom = _rooms[lastRoomId]; changeRoom(curRoomId); diff --git a/engines/supernova2/supernova2.cpp b/engines/supernova2/supernova2.cpp index 532488faed..e59f07d84a 100644 --- a/engines/supernova2/supernova2.cpp +++ b/engines/supernova2/supernova2.cpp @@ -350,9 +350,9 @@ void Supernova2Engine::paletteBrightness() { _screen->paletteBrightness(); } -void Supernova2Engine::paletteFadeOut() { +void Supernova2Engine::paletteFadeOut(int minBrightness) { if (!shouldQuit()) - _screen->paletteFadeOut(); + _screen->paletteFadeOut(minBrightness); } void Supernova2Engine::paletteFadeIn() { diff --git a/engines/supernova2/supernova2.h b/engines/supernova2/supernova2.h index 748eef3e19..071955f47f 100644 --- a/engines/supernova2/supernova2.h +++ b/engines/supernova2/supernova2.h @@ -100,7 +100,7 @@ public: void playSound(AudioId sample); void playSound(MusicId index); void paletteFadeIn(); - void paletteFadeOut(); + void paletteFadeOut(int minBrightness = 0); void paletteBrightness(); void renderImage(int section); void renderImage(ImageId id, bool removeImage = false); -- cgit v1.2.3