diff options
Diffstat (limited to 'engines/toon/toon.cpp')
-rw-r--r-- | engines/toon/toon.cpp | 364 |
1 files changed, 355 insertions, 9 deletions
diff --git a/engines/toon/toon.cpp b/engines/toon/toon.cpp index 2f5051c157..9e2905f454 100644 --- a/engines/toon/toon.cpp +++ b/engines/toon/toon.cpp @@ -210,6 +210,9 @@ void ToonEngine::parseInput() { if (event.kbd.keycode == Common::KEYCODE_s && !hasModifier) { _audioManager->muteSfx(!_audioManager->isSfxMuted()); } + if (event.kbd.keycode == Common::KEYCODE_F1 && !hasModifier && !_gameState->_inMenu) { + showOptions(); + } if (event.kbd.flags & Common::KBD_ALT) { int slotNum = event.kbd.keycode - (event.kbd.keycode >= Common::KEYCODE_KP0 ? Common::KEYCODE_KP0 : Common::KEYCODE_0); @@ -255,7 +258,7 @@ void ToonEngine::parseInput() { } } - if (!_gameState->_inConversation && !_gameState->_mouseHidden && !_gameState->_inInventory) { + if (!_gameState->_inConversation && !_gameState->_mouseHidden && !_gameState->_inInventory && !_gameState->_inMenu) { selectHotspot(); clickEvent(); } @@ -576,7 +579,29 @@ enum MainMenuMasks { MAINMENUMASK_EVERYWHERE = 3 }; -struct MainMenuFile { +enum OptionMenuSelections { + OPTIONMENUHOTSPOT_NONE = 0, + OPTIONMENUHOTSPOT_PLAY = 1, + OPTIONMENUHOTSPOT_QUIT = 2, + OPTIONMENUHOTSPOT_TEXT = 3, + OPTIONMENUHOTSPOT_TEXTSPEED = 4, + OPTIONMENUHOTSPOT_VOLUMESFX = 5, + OPTIONMENUHOTSPOT_VOLUMESFXSLIDER = 6, + OPTIONMENUHOTSPOT_VOLUMEMUSIC = 7, + OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER = 8, + OPTIONMENUHOTSPOT_VOLUMEVOICE = 9, + OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER = 10, + OPTIONMENUHOTSPOT_SPEAKERBUTTON = 11, + OPTIONMENUHOTSPOT_SPEAKERLEVER = 12, + OPTIONMENUHOTSPOT_VIDEO_MODE = 13 +}; + +enum OptionMenuMasks { + OPTIONMENUMASK_EVERYWHERE = 1 +}; + + +struct MenuFile { int menuMask; int id; const char *animationFile; @@ -584,7 +609,7 @@ struct MainMenuFile { }; #define MAINMENU_ENTRYCOUNT 12 -static const MainMenuFile mainMenuFiles[] = { +static const MenuFile mainMenuFiles[] = { { MAINMENUMASK_BASE, MAINMENUHOTSPOT_START, "STARTBUT.CAF", 0 }, // "Start" button { MAINMENUMASK_BASE, MAINMENUHOTSPOT_INTRO, "INTROBUT.CAF", 0 }, // "Intro" button { MAINMENUMASK_BASE, MAINMENUHOTSPOT_LOADGAME, "LOADBUT.CAF", 0 }, // "Load Game" button @@ -600,7 +625,38 @@ static const MainMenuFile mainMenuFiles[] = { { MAINMENUMASK_HOTKEYS, MAINMENUHOTSPOT_HOTKEYSCLOSE, "HOTKEYS.CAF", 0 } // Hotkeys display - clicking on it will close hotkeys }; -struct MainMenuEntry { +#define OPTIONMENU_ENTRYCOUNT 27 +static const MenuFile optionMenuFiles[] = { + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_PLAY, "PLAYBUTN.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_QUIT, "QUITBUTN.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VIDEO_MODE, "VIDMODE.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXTSPEED, "TXTSPEED.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_TEXT, "TEXTDIAL.CAF", 0}, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFX, "SFXBUTN.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMESFXSLIDER, "SFXSLDR.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICE, "VOICEBTN.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER, "VOICESLD.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSIC, "MUSICBTN.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER, "MUSICSLD.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERBUTTON, "XTRABUTN.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_SPEAKERLEVER, "XTRALEVR.CAF", 0}, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAL.CAF", 6 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "ANTENNAR.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "BIGREDL.CAF", 6 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "BIGREDR.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "GRIDLTEL.CAF", 6 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "GRIDLTER.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "LSPEAKR.CAF", 0 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "RSPEAKR.CAF", 0 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "STARLITL.CAF", 6 }, // "Start" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "STARLITR.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE1.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE2.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE3.CAF", 6 }, // "Intro" button + { OPTIONMENUMASK_EVERYWHERE, OPTIONMENUHOTSPOT_NONE, "CHASE4.CAF", 6 } // "Intro" button +}; + +struct MenuEntry { int menuMask; int id; Animation *animation; @@ -608,15 +664,291 @@ struct MainMenuEntry { int animateOnFrame; int animateCurFrame; int activeFrame; + bool playOnce; }; +bool ToonEngine::showOptions() { + + storePalette(); + fadeOut(5); + Picture* optionPicture = new Picture(this); + optionPicture->loadPicture("OPTIONS.CPS"); + optionPicture->setupPalette(); + flushPalette(true); + + int16 oldScrollValue = _gameState->_currentScrollValue; + _gameState->_currentScrollValue = 0; + + bool oldMouseHidden = _gameState->_mouseHidden; + _gameState->_mouseHidden = false; + + MenuEntry entries[OPTIONMENU_ENTRYCOUNT]; + + for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) { + entries[entryNr].menuMask = optionMenuFiles[entryNr].menuMask; + entries[entryNr].id = optionMenuFiles[entryNr].id; + entries[entryNr].animation = new Animation(this); + entries[entryNr].animation->loadAnimation(optionMenuFiles[entryNr].animationFile); + if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE) + entries[entryNr].rect = entries[entryNr].animation->getRect(); + entries[entryNr].animateOnFrame = optionMenuFiles[entryNr].animateOnFrame; + entries[entryNr].animateCurFrame = 0; + entries[entryNr].activeFrame = 0; + entries[entryNr].playOnce = false; + } + + entries[10].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) * (entries[10].animation->_numFrames - 1) / 256; + entries[8].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) * (entries[8].animation->_numFrames - 1) / 256; + entries[6].activeFrame = _audioManager->_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) * (entries[6].animation->_numFrames - 1) / 256; + + entries[9].activeFrame = _audioManager->isMusicMuted() ? 0 : 3; + entries[7].activeFrame = _audioManager->isVoiceMuted() ? 0 : 3; + entries[5].activeFrame = _audioManager->isSfxMuted() ? 0 : 3; + + entries[2].activeFrame = entries[2].animation->_numFrames - 1; + + if (!_showConversationText) { + entries[4].activeFrame = 4; + } else if (_useAlternativeFont) { + entries[4].activeFrame = 8; + } else { + entries[4].activeFrame = 0; + } + + setCursor(0); + + int menuMask = OPTIONMENUMASK_EVERYWHERE; + int ratioX = 0; + bool doExit = false; + bool exitGame = false; + _gameState->_inMenu = true; + dirtyAllScreen(); + _firstFrame = true; + + while (!doExit) { + + int clickingOn = OPTIONMENUHOTSPOT_NONE; + int clickingOnSprite = 0; + int clickRelease = false; + + while (!clickRelease) { + + if (_dirtyAll) { + optionPicture->draw(*_mainSurface, 0, 0, 0, 0); + addDirtyRect(0, 0, TOON_SCREEN_WIDTH, TOON_SCREEN_HEIGHT); + } else { + optionPicture->drawWithRectList(*_mainSurface, 0, 0, 0, 0, _dirtyRects); + } + clearDirtyRects(); + + for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) { + if (entries[entryNr].menuMask & menuMask) { + if (entries[entryNr].animateOnFrame) { + entries[entryNr].animateCurFrame++; + if (entries[entryNr].animateOnFrame <= entries[entryNr].animateCurFrame) { + entries[entryNr].activeFrame++; + if (entries[entryNr].activeFrame >= entries[entryNr].animation->_numFrames) { + entries[entryNr].activeFrame = 0; + if (entries[entryNr].playOnce) { + entries[entryNr].animateOnFrame = 0; + entries[entryNr].playOnce = false; + } + if (entryNr == 20 && entries[entryNr].animateOnFrame > 0) { + playSFX(-3, 128); + } + } + entries[entryNr].animateCurFrame = 0; + } + } + int32 frameNr = entries[entryNr].activeFrame; + entries[entryNr].animation->drawFrame(*_mainSurface, frameNr, 0, 0); + } + } + + parseInput(); + + copyToVirtualScreen(true); + if (_firstFrame) { + _firstFrame = false; + fadeIn(5); + } + _system->delayMillis(17); + + if (_mouseButton & 1) { + // left mouse button pushed down + clickingOn = OPTIONMENUHOTSPOT_NONE; + for (int entryNr = 0; entryNr < OPTIONMENU_ENTRYCOUNT; entryNr++) { + if (entries[entryNr].menuMask & menuMask) { + if (entries[entryNr].id != OPTIONMENUHOTSPOT_NONE) { + if (entries[entryNr].rect.contains(_mouseX, _mouseY)) { + clickingOn = entries[entryNr].id; + clickingOnSprite = entryNr; + ratioX = (_mouseX - entries[entryNr].rect.left) * 256 / entries[entryNr].rect.width(); + } + } + } + } + } else { + // left mouse button released/not pushed down + if (clickingOn != OPTIONMENUHOTSPOT_NONE) + clickRelease = true; + } + + // handle sliders + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSICSLIDER) { + entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256; + int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames; + _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, vol); + } + + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICESLIDER) { + entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256; + int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames; + _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, vol); + } + + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFXSLIDER) { + entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256; + int vol = entries[clickingOnSprite].activeFrame * 256 / entries[clickingOnSprite].animation->_numFrames; + _audioManager->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, vol); + } + + if (clickingOn == OPTIONMENUHOTSPOT_TEXTSPEED) { + entries[clickingOnSprite].activeFrame = ratioX * (entries[clickingOnSprite].animation->_numFrames) / 256; + } + + if (clickingOn == OPTIONMENUHOTSPOT_PLAY) { + entries[0].activeFrame = entries[0].animation->_numFrames - 1; + } else { + entries[0].activeFrame = 0; + } + + if (clickingOn == OPTIONMENUHOTSPOT_QUIT) { + entries[1].activeFrame = entries[1].animation->_numFrames - 1; + } else { + entries[1].activeFrame = 0; + } + + if (_shouldQuit) { + clickingOn = OPTIONMENUHOTSPOT_NONE; + clickRelease = true; + doExit = true; + } + } + + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEMUSIC) { + if (entries[9].activeFrame == 0) { + entries[9].activeFrame = 3; + _audioManager->muteMusic(false); + } else { + entries[9].activeFrame = 0; + _audioManager->muteMusic(true); + } + playSFX(-7, 128); + } + + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMEVOICE) { + if (entries[7].activeFrame == 0) { + entries[7].activeFrame = 3; + _audioManager->muteVoice(false); + } else { + entries[7].activeFrame = 0; + _audioManager->muteVoice(true); + } + playSFX(-7, 128); + } + + if (clickingOn == OPTIONMENUHOTSPOT_VOLUMESFX) { + if (entries[5].activeFrame == 0) { + entries[5].activeFrame = 3; + _audioManager->muteSfx(false); + } else { + entries[5].activeFrame = 0; + _audioManager->muteSfx(true); + } + playSFX(-7, 128); + } + + if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERBUTTON) { + entries[11].animateOnFrame = 4; + entries[11].playOnce = true; + + entries[19].animateOnFrame = 4; + entries[19].playOnce = true; + + playSFX(-10, 128); + _audioManager->playVoice(316, true); + } + + if (clickingOn == OPTIONMENUHOTSPOT_SPEAKERLEVER) { + + entries[12].activeFrame = 1 - entries[12].activeFrame; + if(entries[12].activeFrame == 1) { + entries[20].animateOnFrame = 4; + entries[20].playOnce = false; + playSFX(-3, 128); + } else { + entries[20].playOnce = true; + } + playSFX(-9, 128); + } + + if (clickingOn == OPTIONMENUHOTSPOT_TEXT) { + + if (entries[4].activeFrame == 0) { + _showConversationText = false; + entries[4].activeFrame = 4; + } else if (entries[4].activeFrame == 4) { + _showConversationText = true; + setFont(true); + entries[4].activeFrame = 8; + } else if(entries[4].activeFrame == 8) { + _showConversationText = true; + setFont(false); + entries[4].activeFrame = 0; + } + + playSFX(-9, 128); + } + + // don't allow change to video mode + if (clickingOn == OPTIONMENUHOTSPOT_VIDEO_MODE) { + playSoundWrong(); + } + + if (clickingOn == OPTIONMENUHOTSPOT_PLAY) { + doExit = true; + exitGame = false; + _audioManager->playSFX(10, 128, true); + } + + if (clickingOn == OPTIONMENUHOTSPOT_QUIT) { + doExit = true; + exitGame = true; + _shouldQuit = true; + _audioManager->playSFX(10, 128, true); + } + } + + fadeOut(5); + _gameState->_mouseHidden = oldMouseHidden; + _gameState->_inMenu = false; + _firstFrame = true; + _gameState->_currentScrollValue = oldScrollValue; + + restorePalette(); + dirtyAllScreen(); + + return exitGame; +} + bool ToonEngine::showMainmenu(bool &loadedGame) { Picture *mainmenuPicture = new Picture(this); mainmenuPicture->loadPicture("TITLESCR.CPS"); mainmenuPicture->setupPalette(); flushPalette(false); - MainMenuEntry entries[MAINMENU_ENTRYCOUNT]; + MenuEntry entries[MAINMENU_ENTRYCOUNT]; for (int entryNr = 0; entryNr < MAINMENU_ENTRYCOUNT; entryNr++) { entries[entryNr].menuMask = mainMenuFiles[entryNr].menuMask; @@ -630,7 +962,7 @@ bool ToonEngine::showMainmenu(bool &loadedGame) { entries[entryNr].activeFrame = 0; } - setCursor(1); + setCursor(0); bool doExit = false; bool exitGame = false; @@ -822,6 +1154,7 @@ ToonEngine::ToonEngine(OSystem *syst, const ADGameDescription *gameDescription) _inventoryPicture = NULL; _currentMask = NULL; _showConversationText = true; + _useAlternativeFont = false; _isDemo = _gameDescription->flags & ADGF_DEMO; DebugMan.addDebugChannel(kDebugAnim, "Anim", "Animation debug level"); @@ -1452,7 +1785,7 @@ int32 ToonEngine::runEventScript(int32 x, int32 y, int32 mode, int32 id, int32 s _currentScriptRegion++; _script->start(status, 1); - while (_script->run(status)) + while (_script->run(status) && !_shouldQuit) waitForScriptStep(); _currentScriptRegion--; @@ -1853,6 +2186,17 @@ void ToonEngine::initFonts() { _fontEZ = new Animation(this); _fontEZ->loadAnimation("EZFONT.CAF"); + + setFont(false); +} + +void ToonEngine::setFont(bool alternative) { + if (alternative) { + _currentFont = _fontEZ; + } else { + _currentFont = _fontToon; + } + _useAlternativeFont = alternative; } void ToonEngine::drawInfoLine() { @@ -1870,7 +2214,7 @@ void ToonEngine::drawInfoLine() { } if (infoTool) { _fontRenderer->setFontColor(0xc8, 0xdd, 0xe3); - _fontRenderer->setFont(_fontToon); + _fontRenderer->setFont(_currentFont); _fontRenderer->renderText(320 + _gameState->_currentScrollValue, 398, infoTool, 5); } } @@ -1998,6 +2342,8 @@ int32 ToonEngine::simpleCharacterTalk(int32 dialogid) { _audioManager->playVoice(myId, false); } else { myId = _genericTexts->getId(dialogid - 1000); + if (myId == -1) + return 0; _audioManager->playVoice(myId, true); } @@ -2936,7 +3282,7 @@ Character *ToonEngine::getCharacterById(int32 charId) { void ToonEngine::drawConversationLine() { if (_currentTextLine && _showConversationText) { _fontRenderer->setFontColorByCharacter(_currentTextLineCharacterId); - _fontRenderer->setFont(_fontToon); + _fontRenderer->setFont(_currentFont); _fontRenderer->renderMultiLineText(_currentTextLineX, _currentTextLineY, _currentTextLine, 0); } } |