mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
1328 lines
33 KiB
C++
1328 lines
33 KiB
C++
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "lastexpress/menu/menu.h"
|
|
|
|
// Data
|
|
#include "lastexpress/data/animation.h"
|
|
#include "lastexpress/data/cursor.h"
|
|
#include "lastexpress/data/snd.h"
|
|
#include "lastexpress/data/scene.h"
|
|
|
|
#include "lastexpress/fight/fight.h"
|
|
|
|
#include "lastexpress/game/entities.h"
|
|
#include "lastexpress/game/inventory.h"
|
|
#include "lastexpress/game/logic.h"
|
|
#include "lastexpress/game/savegame.h"
|
|
#include "lastexpress/game/savepoint.h"
|
|
#include "lastexpress/game/scenes.h"
|
|
#include "lastexpress/game/state.h"
|
|
|
|
#include "lastexpress/menu/clock.h"
|
|
#include "lastexpress/menu/trainline.h"
|
|
|
|
#include "lastexpress/sound/queue.h"
|
|
|
|
#include "lastexpress/graphics.h"
|
|
#include "lastexpress/lastexpress.h"
|
|
#include "lastexpress/resource.h"
|
|
|
|
#include "common/rational.h"
|
|
|
|
#define getNextGameId() (GameId)((_gameId + 1) % 6)
|
|
|
|
namespace LastExpress {
|
|
|
|
// Bottom-left buttons (quit.seq)
|
|
enum StartMenuButtons {
|
|
kButtonVolumeDownPushed,
|
|
kButtonVolumeDown,
|
|
kButtonVolume,
|
|
kButtonVolumeUp,
|
|
kButtonVolumeUpPushed,
|
|
kButtonBrightnessDownPushed, // 5
|
|
kButtonBrightnessDown,
|
|
kButtonBrightness,
|
|
kButtonBrightnessUp,
|
|
kButtonBrightnessUpPushed,
|
|
kButtonQuit, // 10
|
|
kButtonQuitPushed
|
|
};
|
|
|
|
// Egg buttons (buttns.seq)
|
|
enum StartMenuEggButtons {
|
|
kButtonShield,
|
|
kButtonRewind,
|
|
kButtonRewindPushed,
|
|
kButtonForward,
|
|
kButtonForwardPushed,
|
|
kButtonCredits, // 5
|
|
kButtonCreditsPushed,
|
|
kButtonContinue
|
|
};
|
|
|
|
// Tooltips sequence (helpnewr.seq)
|
|
enum StartMenuTooltips {
|
|
kTooltipInsertCd1,
|
|
kTooltipInsertCd2,
|
|
kTooltipInsertCd3,
|
|
kTooltipContinueGame,
|
|
kTooltipReplayGame,
|
|
kTooltipContinueRewoundGame, // 5
|
|
kTooltipViewGameEnding,
|
|
kTooltipStartAnotherGame,
|
|
kTooltipVolumeUp,
|
|
kTooltipVolumeDown,
|
|
kTooltipBrightnessUp, // 10
|
|
kTooltipBrightnessDown,
|
|
kTooltipQuit,
|
|
kTooltipRewindParis,
|
|
kTooltipForwardStrasbourg,
|
|
kTooltipRewindStrasbourg, // 15
|
|
kTooltipRewindMunich,
|
|
kTooltipForwardMunich,
|
|
kTooltipForwardVienna,
|
|
kTooltipRewindVienna,
|
|
kTooltipRewindBudapest, // 20
|
|
kTooltipForwardBudapest,
|
|
kTooltipForwardBelgrade,
|
|
kTooltipRewindBelgrade,
|
|
kTooltipForwardConstantinople,
|
|
kTooltipSwitchBlueGame, // 25
|
|
kTooltipSwitchRedGame,
|
|
kTooltipSwitchGoldGame,
|
|
kTooltipSwitchGreenGame,
|
|
kTooltipSwitchTealGame,
|
|
kTooltipSwitchPurpleGame, // 30
|
|
kTooltipPlayNewGame,
|
|
kTooltipCredits,
|
|
kTooltipFastForward,
|
|
kTooltipRewind
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// DATA
|
|
//////////////////////////////////////////////////////////////////////////
|
|
static const struct {
|
|
TimeValue time;
|
|
uint index;
|
|
StartMenuTooltips rewind;
|
|
StartMenuTooltips forward;
|
|
} _cityButtonsInfo[7] = {
|
|
{kTimeCityParis, 64, kTooltipRewindParis, kTooltipRewindParis},
|
|
{kTimeCityStrasbourg, 128, kTooltipRewindStrasbourg, kTooltipForwardStrasbourg},
|
|
{kTimeCityMunich, 129, kTooltipRewindMunich, kTooltipForwardMunich},
|
|
{kTimeCityVienna, 130, kTooltipRewindVienna, kTooltipForwardVienna},
|
|
{kTimeCityBudapest, 131, kTooltipRewindBudapest, kTooltipForwardBudapest},
|
|
{kTimeCityBelgrade, 132, kTooltipRewindBelgrade, kTooltipForwardBelgrade},
|
|
{kTimeCityConstantinople, 192, kTooltipForwardConstantinople, kTooltipForwardConstantinople}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Menu
|
|
//////////////////////////////////////////////////////////////////////////
|
|
Menu::Menu(LastExpressEngine *engine) : _engine(engine),
|
|
_seqTooltips(nullptr), _seqEggButtons(nullptr), _seqButtons(nullptr), _seqAcorn(nullptr), _seqCity1(nullptr), _seqCity2(nullptr), _seqCity3(nullptr), _seqCredits(nullptr),
|
|
_gameId(kGameBlue), _hasShownStartScreen(false), _hasShownIntro(false),
|
|
_isShowingCredits(false), _isGameStarted(false), _isShowingMenu(false),
|
|
_creditsSequenceIndex(0), _checkHotspotsTicks(15), _mouseFlags(Common::EVENT_INVALID), _lastHotspot(nullptr),
|
|
_currentTime(kTimeNone), _lowerTime(kTimeNone), _time(kTimeNone), _currentIndex(0), _index(0), _lastIndex(0), _delta(0), _handleTimeDelta(false) {
|
|
|
|
_clock = new Clock(_engine);
|
|
_trainLine = new TrainLine(_engine);
|
|
}
|
|
|
|
Menu::~Menu() {
|
|
SAFE_DELETE(_clock);
|
|
SAFE_DELETE(_trainLine);
|
|
|
|
SAFE_DELETE(_seqTooltips);
|
|
SAFE_DELETE(_seqEggButtons);
|
|
SAFE_DELETE(_seqButtons);
|
|
SAFE_DELETE(_seqAcorn);
|
|
SAFE_DELETE(_seqCity1);
|
|
SAFE_DELETE(_seqCity2);
|
|
SAFE_DELETE(_seqCity3);
|
|
SAFE_DELETE(_seqCredits);
|
|
|
|
_lastHotspot = nullptr;
|
|
|
|
// Cleanup frames
|
|
for (MenuFrames::iterator it = _frames.begin(); it != _frames.end(); it++)
|
|
SAFE_DELETE(it->_value);
|
|
|
|
_frames.clear();
|
|
|
|
// Zero passed pointers
|
|
_engine = nullptr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Setup
|
|
void Menu::setup() {
|
|
|
|
// Clear drawing queue
|
|
getScenes()->removeAndRedraw(&_frames[kOverlayAcorn], false);
|
|
SAFE_DELETE(_seqAcorn);
|
|
|
|
// Load Menu scene
|
|
// + 1 = normal menu with open egg / clock
|
|
// + 2 = shield menu, when no savegame exists (no game has been started)
|
|
_isGameStarted = _lowerTime >= kTimeStartGame;
|
|
getScenes()->loadScene((SceneIndex)(_isGameStarted ? _gameId * 5 + 1 : _gameId * 5 + 2));
|
|
getFlags()->shouldRedraw = true;
|
|
getLogic()->updateCursor();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Load Acorn sequence
|
|
_seqAcorn = loadSequence(getAcornSequenceName(_isGameStarted ? getNextGameId() : kGameBlue));
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Check if we loaded sequences before
|
|
if (_seqTooltips && _seqTooltips->count() > 0)
|
|
return;
|
|
|
|
// Load all static data
|
|
_seqTooltips = loadSequence("helpnewr.seq");
|
|
_seqEggButtons = loadSequence("buttns.seq");
|
|
_seqButtons = loadSequence("quit.seq");
|
|
_seqCity1 = loadSequence("jlinetl.seq");
|
|
_seqCity2 = loadSequence("jlinecen.seq");
|
|
_seqCity3 = loadSequence("jlinebr.seq");
|
|
_seqCredits = loadSequence("credits.seq");
|
|
|
|
_frames[kOverlayTooltip] = new SequenceFrame(_seqTooltips);
|
|
_frames[kOverlayEggButtons] = new SequenceFrame(_seqEggButtons);
|
|
_frames[kOverlayButtons] = new SequenceFrame(_seqButtons);
|
|
_frames[kOverlayAcorn] = new SequenceFrame(_seqAcorn);
|
|
_frames[kOverlayCity1] = new SequenceFrame(_seqCity1);
|
|
_frames[kOverlayCity2] = new SequenceFrame(_seqCity2);
|
|
_frames[kOverlayCity3] = new SequenceFrame(_seqCity3);
|
|
_frames[kOverlayCredits] = new SequenceFrame(_seqCredits);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Handle events
|
|
void Menu::eventMouse(const Common::Event &ev) {
|
|
if (!getFlags()->shouldRedraw)
|
|
return;
|
|
|
|
bool redraw = true;
|
|
getFlags()->shouldRedraw = false;
|
|
|
|
// Update coordinates
|
|
setCoords(ev.mouse);
|
|
//_mouseFlags = (Common::EventType)(ev.type & Common::EVENT_LBUTTONUP);
|
|
|
|
if (_isShowingCredits) {
|
|
if (ev.type == Common::EVENT_RBUTTONUP) {
|
|
showFrame(kOverlayCredits, -1, true);
|
|
_isShowingCredits = false;
|
|
}
|
|
|
|
if (ev.type == Common::EVENT_LBUTTONUP) {
|
|
// Last frame of the credits
|
|
if (_seqCredits && _creditsSequenceIndex == _seqCredits->count() - 1) {
|
|
showFrame(kOverlayCredits, -1, true);
|
|
_isShowingCredits = false;
|
|
} else {
|
|
++_creditsSequenceIndex;
|
|
showFrame(kOverlayCredits, _creditsSequenceIndex, true);
|
|
}
|
|
}
|
|
} else {
|
|
// Check for hotspots
|
|
SceneHotspot *hotspot = nullptr;
|
|
getScenes()->get(getState()->scene)->checkHotSpot(ev.mouse, &hotspot);
|
|
|
|
if (_lastHotspot != hotspot || ev.type == Common::EVENT_LBUTTONUP) {
|
|
_lastHotspot = hotspot;
|
|
|
|
if (ev.type == Common::EVENT_MOUSEMOVE) { /* todo check event type */
|
|
if (!_handleTimeDelta && hasTimeDelta())
|
|
setTime();
|
|
}
|
|
|
|
if (hotspot) {
|
|
redraw = handleEvent((StartMenuAction)hotspot->action, ev.type);
|
|
getFlags()->mouseRightClick = false;
|
|
getFlags()->mouseLeftClick = false;
|
|
} else {
|
|
hideOverlays();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (redraw) {
|
|
getFlags()->shouldRedraw = true;
|
|
askForRedraw();
|
|
}
|
|
}
|
|
|
|
void Menu::eventTick(const Common::Event&) {
|
|
if (hasTimeDelta())
|
|
adjustTime();
|
|
else if (_handleTimeDelta)
|
|
_handleTimeDelta = false;
|
|
|
|
// Check hotspots
|
|
if (!--_checkHotspotsTicks) {
|
|
checkHotspots();
|
|
_checkHotspotsTicks = 15;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Show the intro and load the main menu scene
|
|
void Menu::show(bool doSavegame, SavegameType type, uint32 value) {
|
|
|
|
if (_isShowingMenu)
|
|
return;
|
|
|
|
_isShowingMenu = true;
|
|
getEntities()->reset();
|
|
|
|
// If no blue savegame exists, this might be the first time we start the game, so we show the full intro
|
|
if (!getFlags()->mouseRightClick) {
|
|
if (!SaveLoad::isSavegameValid(kGameBlue) && _engine->getResourceManager()->loadArchive(kArchiveCd1)) {
|
|
|
|
if (!_hasShownIntro) {
|
|
// Show Broderbrund logo
|
|
Animation animation;
|
|
if (animation.load(getArchive("1930.nis")))
|
|
animation.play();
|
|
|
|
getFlags()->mouseRightClick = false;
|
|
|
|
// Play intro music
|
|
getSound()->playSoundWithSubtitles("MUS001.SND", kSoundTypeIntro | kVolumeFull, kEntityPlayer);
|
|
|
|
// Show The Smoking Car logo
|
|
if (animation.load(getArchive("1931.nis")))
|
|
animation.play();
|
|
|
|
_hasShownIntro = true;
|
|
}
|
|
} else {
|
|
// Only show the quick intro
|
|
if (!_hasShownStartScreen) {
|
|
getSound()->playSoundWithSubtitles("MUS018.SND", kSoundTypeIntro | kVolumeFull, kEntityPlayer);
|
|
getScenes()->loadScene(kSceneStartScreen);
|
|
|
|
// Original game waits 60 frames and loops Sound::unknownFunction1 unless the right button is pressed
|
|
uint32 nextFrameCount = getFrameCount() + 60;
|
|
while (getFrameCount() < nextFrameCount) {
|
|
_engine->pollEvents();
|
|
|
|
if (getFlags()->mouseRightClick)
|
|
break;
|
|
|
|
getSoundQueue()->updateQueue();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_hasShownStartScreen = true;
|
|
|
|
// Init Menu
|
|
init(doSavegame, type, value);
|
|
|
|
// Setup sound
|
|
getSoundQueue()->stopAmbient();
|
|
getSoundQueue()->stopAllExcept(kSoundTagIntro, kSoundTagMenu);
|
|
if (getSoundQueue()->isBuffered("TIMER"))
|
|
getSoundQueue()->stop("TIMER");
|
|
|
|
// Init flags & misc
|
|
_isShowingCredits = false;
|
|
_handleTimeDelta = hasTimeDelta();
|
|
getInventory()->unselectItem();
|
|
|
|
// Set Cursor type
|
|
_engine->getCursor()->setStyle(kCursorNormal);
|
|
_engine->getCursor()->show(true);
|
|
|
|
setup();
|
|
checkHotspots();
|
|
|
|
// Set event handlers
|
|
SET_EVENT_HANDLERS(Menu, this);
|
|
}
|
|
|
|
bool Menu::handleEvent(StartMenuAction action, Common::EventType type) {
|
|
bool clicked = (type == Common::EVENT_LBUTTONUP);
|
|
|
|
switch(action) {
|
|
default:
|
|
hideOverlays();
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuCredits:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
if (clicked) {
|
|
showFrame(kOverlayEggButtons, kButtonCreditsPushed, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
|
|
hideOverlays();
|
|
|
|
_isShowingCredits = true;
|
|
_creditsSequenceIndex = 0;
|
|
|
|
showFrame(kOverlayCredits, 0, true);
|
|
} else {
|
|
// TODO check flags ?
|
|
|
|
showFrame(kOverlayEggButtons, kButtonCredits, true);
|
|
showFrame(kOverlayTooltip, kTooltipCredits, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuQuitGame:
|
|
showFrame(kOverlayTooltip, kTooltipQuit, true);
|
|
|
|
if (clicked) {
|
|
showFrame(kOverlayButtons, kButtonQuitPushed, true);
|
|
|
|
getSoundQueue()->stopAll();
|
|
getSoundQueue()->updateQueue();
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
|
|
// FIXME uncomment when sound queue is properly implemented
|
|
/*while (getSoundQueue()->isBuffered("LIB046"))
|
|
getSoundQueue()->updateQueue();*/
|
|
|
|
getFlags()->shouldRedraw = false;
|
|
|
|
Engine::quitGame();
|
|
|
|
return false;
|
|
} else {
|
|
showFrame(kOverlayButtons, kButtonQuit, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuCase4:
|
|
if (clicked)
|
|
_index = 0;
|
|
// fall through
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuContinue: {
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
// Determine the proper CD archive
|
|
ArchiveIndex cd = kArchiveCd1;
|
|
if (getProgress().chapter > kChapter1)
|
|
cd = (getProgress().chapter > kChapter3) ? kArchiveCd3 : kArchiveCd2;
|
|
|
|
// Show tooltips & buttons to start a game, continue a game or load the proper cd
|
|
if (ResourceManager::isArchivePresent(cd)) {
|
|
if (_isGameStarted) {
|
|
showFrame(kOverlayEggButtons, kButtonContinue, true);
|
|
|
|
if (_lastIndex == _index) {
|
|
showFrame(kOverlayTooltip, getSaveLoad()->isGameFinished(_index, _lastIndex) ? kTooltipViewGameEnding : kTooltipContinueGame, true);
|
|
} else {
|
|
showFrame(kOverlayTooltip, kTooltipContinueRewoundGame, true);
|
|
}
|
|
|
|
} else {
|
|
showFrame(kOverlayEggButtons, kButtonShield, true);
|
|
showFrame(kOverlayTooltip, kTooltipPlayNewGame, true);
|
|
}
|
|
} else {
|
|
showFrame(kOverlayEggButtons, -1, true);
|
|
showFrame(kOverlayTooltip, cd - 1, true);
|
|
}
|
|
|
|
if (!clicked)
|
|
break;
|
|
|
|
// Try loading the archive file
|
|
if (!_engine->getResourceManager()->loadArchive(cd))
|
|
break;
|
|
|
|
// Load the train data file and setup game
|
|
getScenes()->loadSceneDataFile(cd);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
|
|
// Setup new game
|
|
getSavePoints()->reset();
|
|
setLogicEventHandlers();
|
|
|
|
if (_index) {
|
|
getSoundQueue()->fade(kSoundTagIntro);
|
|
} else {
|
|
if (!getFlags()->mouseRightClick) {
|
|
getScenes()->loadScene((SceneIndex)(5 * _gameId + 3));
|
|
|
|
if (!getFlags()->mouseRightClick) {
|
|
getScenes()->loadScene((SceneIndex)(5 * _gameId + 4));
|
|
|
|
if (!getFlags()->mouseRightClick) {
|
|
getScenes()->loadScene((SceneIndex)(5 * _gameId + 5));
|
|
|
|
if (!getFlags()->mouseRightClick) {
|
|
getSoundQueue()->fade(kSoundTagIntro);
|
|
|
|
// Show intro
|
|
Animation animation;
|
|
if (animation.load(getArchive("1601.nis")))
|
|
animation.play();
|
|
|
|
getEvent(kEventIntro) = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!getEvent(kEventIntro)) {
|
|
getEvent(kEventIntro) = 1;
|
|
|
|
getSoundQueue()->fade(kSoundTagIntro);
|
|
}
|
|
}
|
|
|
|
// Setup game
|
|
getFlags()->isGameRunning = true;
|
|
startGame();
|
|
|
|
if (!_isShowingMenu)
|
|
getInventory()->show();
|
|
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuSwitchSaveGame:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
if (clicked) {
|
|
showFrame(kOverlayAcorn, 1, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB047");
|
|
|
|
// Setup new menu screen
|
|
switchGame();
|
|
setup();
|
|
|
|
// Set fight state to 0
|
|
getFight()->resetState();
|
|
|
|
return true;
|
|
}
|
|
|
|
// TODO Check for flag
|
|
|
|
showFrame(kOverlayAcorn, 0, true);
|
|
|
|
if (_isGameStarted) {
|
|
showFrame(kOverlayTooltip, kTooltipSwitchBlueGame, true);
|
|
break;
|
|
}
|
|
|
|
if (_gameId == kGameGold) {
|
|
showFrame(kOverlayTooltip, kTooltipSwitchBlueGame, true);
|
|
break;
|
|
}
|
|
|
|
if (!SaveLoad::isSavegameValid(getNextGameId())) {
|
|
showFrame(kOverlayTooltip, kTooltipStartAnotherGame, true);
|
|
break;
|
|
}
|
|
|
|
// Stupid tooltips ids are not in order, so we can't just increment them...
|
|
switch(_gameId) {
|
|
default:
|
|
break;
|
|
|
|
case kGameBlue:
|
|
showFrame(kOverlayTooltip, kTooltipSwitchRedGame, true);
|
|
break;
|
|
|
|
case kGameRed:
|
|
showFrame(kOverlayTooltip, kTooltipSwitchGreenGame, true);
|
|
break;
|
|
|
|
case kGameGreen:
|
|
showFrame(kOverlayTooltip, kTooltipSwitchPurpleGame, true);
|
|
break;
|
|
|
|
case kGamePurple:
|
|
showFrame(kOverlayTooltip, kTooltipSwitchTealGame, true);
|
|
break;
|
|
|
|
case kGameTeal:
|
|
showFrame(kOverlayTooltip, kTooltipSwitchGoldGame, true);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuRewindGame:
|
|
if (!_index || _currentTime < _time) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
if (clicked) {
|
|
if (hasTimeDelta())
|
|
_handleTimeDelta = false;
|
|
|
|
showFrame(kOverlayEggButtons, kButtonRewindPushed, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
|
|
rewindTime();
|
|
|
|
_handleTimeDelta = false;
|
|
} else {
|
|
showFrame(kOverlayEggButtons, kButtonRewind, true);
|
|
showFrame(kOverlayTooltip, kTooltipRewind, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuForwardGame:
|
|
if (_lastIndex <= _index || _currentTime > _time) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
if (clicked) {
|
|
if (hasTimeDelta())
|
|
_handleTimeDelta = false;
|
|
|
|
showFrame(kOverlayEggButtons, kButtonForwardPushed, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
|
|
forwardTime();
|
|
|
|
_handleTimeDelta = false;
|
|
} else {
|
|
showFrame(kOverlayEggButtons, kButtonForward, true);
|
|
showFrame(kOverlayTooltip, kTooltipFastForward, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuParis:
|
|
moveToCity(kParis, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuStrasBourg:
|
|
moveToCity(kStrasbourg, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuMunich:
|
|
moveToCity(kMunich, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuVienna:
|
|
moveToCity(kVienna, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuBudapest:
|
|
moveToCity(kBudapest, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuBelgrade:
|
|
moveToCity(kBelgrade, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuConstantinople:
|
|
moveToCity(kConstantinople, clicked);
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuDecreaseVolume:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
// Cannot decrease volume further
|
|
if (getVolume() == 0) {
|
|
showFrame(kOverlayButtons, kButtonVolume, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
break;
|
|
}
|
|
|
|
showFrame(kOverlayTooltip, kTooltipVolumeDown, true);
|
|
|
|
// Show highlight on button & adjust volume if needed
|
|
if (clicked) {
|
|
showFrame(kOverlayButtons, kButtonVolumeDownPushed, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
setVolume(getVolume() - 1);
|
|
|
|
getSaveLoad()->saveVolumeBrightness();
|
|
|
|
uint32 nextFrameCount = getFrameCount() + 15;
|
|
while (nextFrameCount > getFrameCount()) {
|
|
_engine->pollEvents();
|
|
|
|
getSoundQueue()->updateQueue();
|
|
}
|
|
} else {
|
|
showFrame(kOverlayButtons, kButtonVolumeDown, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuIncreaseVolume:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
// Cannot increase volume further
|
|
if (getVolume() >= 7) {
|
|
showFrame(kOverlayButtons, kButtonVolume, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
break;
|
|
}
|
|
|
|
showFrame(kOverlayTooltip, kTooltipVolumeUp, true);
|
|
|
|
// Show highlight on button & adjust volume if needed
|
|
if (clicked) {
|
|
showFrame(kOverlayButtons, kButtonVolumeUpPushed, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
setVolume(getVolume() + 1);
|
|
|
|
getSaveLoad()->saveVolumeBrightness();
|
|
|
|
uint32 nextFrameCount = getFrameCount() + 15;
|
|
while (nextFrameCount > getFrameCount()) {
|
|
_engine->pollEvents();
|
|
|
|
getSoundQueue()->updateQueue();
|
|
}
|
|
} else {
|
|
showFrame(kOverlayButtons, kButtonVolumeUp, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuDecreaseBrightness:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
// Cannot increase brightness further
|
|
if (getBrightness() == 0) {
|
|
showFrame(kOverlayButtons, kButtonBrightness, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
break;
|
|
}
|
|
|
|
showFrame(kOverlayTooltip, kTooltipBrightnessDown, true);
|
|
|
|
// Show highlight on button & adjust brightness if needed
|
|
if (clicked) {
|
|
showFrame(kOverlayButtons, kButtonBrightnessDownPushed, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
setBrightness(getBrightness() - 1);
|
|
|
|
getSaveLoad()->saveVolumeBrightness();
|
|
|
|
// Reshow the background and frames (they will pick up the new brightness through the GraphicsManager)
|
|
_engine->getGraphicsManager()->draw(getScenes()->get((SceneIndex)(_isGameStarted ? _gameId * 5 + 1 : _gameId * 5 + 2)), GraphicsManager::kBackgroundC, true);
|
|
showFrame(kOverlayTooltip, kTooltipBrightnessDown, false);
|
|
showFrame(kOverlayButtons, kButtonBrightnessDownPushed, false);
|
|
} else {
|
|
showFrame(kOverlayButtons, kButtonBrightnessDown, true);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
case kMenuIncreaseBrightness:
|
|
if (hasTimeDelta()) {
|
|
hideOverlays();
|
|
break;
|
|
}
|
|
|
|
// Cannot increase brightness further
|
|
if (getBrightness() >= 6) {
|
|
showFrame(kOverlayButtons, kButtonBrightness, true);
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
break;
|
|
}
|
|
|
|
showFrame(kOverlayTooltip, kTooltipBrightnessUp, true);
|
|
|
|
// Show highlight on button & adjust brightness if needed
|
|
if (clicked) {
|
|
showFrame(kOverlayButtons, kButtonBrightnessUpPushed, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
setBrightness(getBrightness() + 1);
|
|
|
|
getSaveLoad()->saveVolumeBrightness();
|
|
|
|
// Reshow the background and frames (they will pick up the new brightness through the GraphicsManager)
|
|
_engine->getGraphicsManager()->draw(getScenes()->get((SceneIndex)(_isGameStarted ? _gameId * 5 + 1 : _gameId * 5 + 2)), GraphicsManager::kBackgroundC, true);
|
|
showFrame(kOverlayTooltip, kTooltipBrightnessUp, false);
|
|
showFrame(kOverlayButtons, kButtonBrightnessUpPushed, false);
|
|
} else {
|
|
showFrame(kOverlayButtons, kButtonBrightnessUp, true);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Menu::setLogicEventHandlers() {
|
|
SET_EVENT_HANDLERS(Logic, getLogic());
|
|
clear();
|
|
_isShowingMenu = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Game-related
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void Menu::init(bool doSavegame, SavegameType type, uint32 value) {
|
|
|
|
bool useSameIndex = true;
|
|
|
|
if (getGlobalTimer()) {
|
|
value = 0;
|
|
|
|
// Check if the CD file is present
|
|
ArchiveIndex index = kArchiveCd1;
|
|
switch (getProgress().chapter) {
|
|
default:
|
|
case kChapter1:
|
|
break;
|
|
|
|
case kChapter2:
|
|
case kChapter3:
|
|
index = kArchiveCd2;
|
|
break;
|
|
|
|
case kChapter4:
|
|
case kChapter5:
|
|
index = kArchiveCd3;
|
|
break;
|
|
}
|
|
|
|
if (ResourceManager::isArchivePresent(index)) {
|
|
setGlobalTimer(0);
|
|
useSameIndex = false;
|
|
|
|
// TODO remove existing savegame and reset index & savegame name
|
|
warning("[Menu::initGame] Not implemented");
|
|
}
|
|
|
|
doSavegame = false;
|
|
} else {
|
|
warning("[Menu::initGame] Renaming saves not implemented");
|
|
}
|
|
|
|
// Create a new savegame if needed
|
|
if (!SaveLoad::isSavegamePresent(_gameId))
|
|
getSaveLoad()->create(_gameId);
|
|
|
|
if (doSavegame)
|
|
getSaveLoad()->saveGame(kSavegameTypeEvent2, kEntityPlayer, kEventNone);
|
|
|
|
if (!getGlobalTimer()) {
|
|
warning("[Menu::initGame] Removing temporary saves not implemented");
|
|
}
|
|
|
|
// Init savegame & menu values
|
|
_lastIndex = getSaveLoad()->init(_gameId, true);
|
|
_lowerTime = getSaveLoad()->getTime(_lastIndex);
|
|
|
|
if (useSameIndex)
|
|
_index = _lastIndex;
|
|
|
|
//if (!getGlobalTimer())
|
|
// _index3 = 0;
|
|
|
|
if (!getProgress().chapter)
|
|
getProgress().chapter = kChapter1;
|
|
|
|
getState()->time = (TimeValue)getSaveLoad()->getTime(_index);
|
|
getProgress().chapter = getSaveLoad()->getChapter(_index);
|
|
|
|
if (_lowerTime >= kTimeStartGame) {
|
|
_currentTime = (uint32)getState()->time;
|
|
_time = (uint32)getState()->time;
|
|
_clock->draw(_time);
|
|
_trainLine->draw(_time);
|
|
|
|
initTime(type, value);
|
|
}
|
|
}
|
|
|
|
// Start a game (or load an existing savegame)
|
|
void Menu::startGame() {
|
|
// Clear savegame headers
|
|
getSaveLoad()->clear();
|
|
|
|
// Hide menu elements
|
|
_clock->clear();
|
|
_trainLine->clear();
|
|
|
|
if (_lastIndex == _index) {
|
|
setGlobalTimer(0);
|
|
if (_index) {
|
|
getSaveLoad()->loadLastGame();
|
|
} else {
|
|
getLogic()->resetState();
|
|
getEntities()->setup(true, kEntityPlayer);
|
|
}
|
|
} else {
|
|
getSaveLoad()->loadGame(_index);
|
|
}
|
|
}
|
|
|
|
// Switch to the next savegame
|
|
void Menu::switchGame() {
|
|
|
|
// Switch back to blue game is the current game is not started
|
|
_gameId = SaveLoad::isSavegameValid(_gameId) ? getNextGameId() : kGameBlue;
|
|
|
|
// Initialize savegame if needed
|
|
if (!SaveLoad::isSavegamePresent(_gameId))
|
|
getSaveLoad()->create(_gameId);
|
|
|
|
getState()->time = kTimeNone;
|
|
|
|
// Clear menu elements
|
|
_clock->clear();
|
|
_trainLine->clear();
|
|
|
|
// Clear loaded savegame data
|
|
getSaveLoad()->clear(true);
|
|
|
|
init(false, kSavegameTypeIndex, 0);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Overlays & elements
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void Menu::checkHotspots() {
|
|
if (!_isShowingMenu)
|
|
return;
|
|
|
|
if (!getFlags()->shouldRedraw)
|
|
return;
|
|
|
|
if (_isShowingCredits)
|
|
return;
|
|
|
|
SceneHotspot *hotspot = nullptr;
|
|
getScenes()->get(getState()->scene)->checkHotSpot(getCoords(), &hotspot);
|
|
|
|
if (hotspot)
|
|
handleEvent((StartMenuAction)hotspot->action, _mouseFlags);
|
|
else
|
|
hideOverlays();
|
|
}
|
|
|
|
void Menu::hideOverlays() {
|
|
_lastHotspot = nullptr;
|
|
|
|
// Hide all menu overlays
|
|
for (MenuFrames::iterator it = _frames.begin(); it != _frames.end(); it++)
|
|
showFrame(it->_key, -1, false);
|
|
|
|
getScenes()->drawFrames(true);
|
|
}
|
|
|
|
void Menu::showFrame(StartMenuOverlay overlayType, int index, bool redraw) {
|
|
if (index == -1) {
|
|
getScenes()->removeFromQueue(_frames[overlayType]);
|
|
} else {
|
|
// Check that the overlay is valid
|
|
if (!_frames[overlayType])
|
|
return;
|
|
|
|
// Remove the frame and add a new one with the proper index
|
|
getScenes()->removeFromQueue(_frames[overlayType]);
|
|
_frames[overlayType]->setFrame((uint16)index);
|
|
getScenes()->addToQueue(_frames[overlayType]);
|
|
}
|
|
|
|
if (redraw)
|
|
getScenes()->drawFrames(true);
|
|
}
|
|
|
|
// Remove all frames from the queue
|
|
void Menu::clear() {
|
|
for (MenuFrames::iterator it = _frames.begin(); it != _frames.end(); it++)
|
|
getScenes()->removeAndRedraw(&it->_value, false);
|
|
|
|
clearBg(GraphicsManager::kBackgroundOverlay);
|
|
}
|
|
|
|
// Get the sequence name to use for the acorn highlight, depending of the currently loaded savegame
|
|
Common::String Menu::getAcornSequenceName(GameId id) const {
|
|
Common::String name = "";
|
|
switch (id) {
|
|
default:
|
|
case kGameBlue:
|
|
name = "aconblu3.seq";
|
|
break;
|
|
|
|
case kGameRed:
|
|
name = "aconred.seq";
|
|
break;
|
|
|
|
case kGameGreen:
|
|
name = "acongren.seq";
|
|
break;
|
|
|
|
case kGamePurple:
|
|
name = "aconpurp.seq";
|
|
break;
|
|
|
|
case kGameTeal:
|
|
name = "aconteal.seq";
|
|
break;
|
|
|
|
case kGameGold:
|
|
name = "acongold.seq";
|
|
break;
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Time
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void Menu::initTime(SavegameType type, uint32 value) {
|
|
if (!value)
|
|
return;
|
|
|
|
// The savegame entry index
|
|
uint32 entryIndex = 0;
|
|
|
|
switch (type) {
|
|
default:
|
|
break;
|
|
|
|
case kSavegameTypeIndex:
|
|
entryIndex = (_index <= value) ? 1 : _index - value;
|
|
break;
|
|
|
|
case kSavegameTypeTime:
|
|
if (value < kTimeStartGame)
|
|
break;
|
|
|
|
entryIndex = _index;
|
|
if (!entryIndex)
|
|
break;
|
|
|
|
// Iterate through existing entries
|
|
do {
|
|
if (getSaveLoad()->getTime(entryIndex) <= value)
|
|
break;
|
|
|
|
entryIndex--;
|
|
} while (entryIndex);
|
|
break;
|
|
|
|
case kSavegameTypeEvent:
|
|
entryIndex = _index;
|
|
if (!entryIndex)
|
|
break;
|
|
|
|
do {
|
|
if (getSaveLoad()->getValue(entryIndex) == value)
|
|
break;
|
|
|
|
entryIndex--;
|
|
} while (entryIndex);
|
|
break;
|
|
|
|
case kSavegameTypeEvent2:
|
|
// TODO rewrite in a more legible way
|
|
if (_index > 1) {
|
|
uint32 index = _index;
|
|
do {
|
|
if (getSaveLoad()->getValue(index) == value)
|
|
break;
|
|
|
|
index--;
|
|
} while (index > 1);
|
|
|
|
entryIndex = index - 1;
|
|
} else {
|
|
entryIndex = _index - 1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (entryIndex) {
|
|
_currentIndex = entryIndex;
|
|
updateTime(getSaveLoad()->getTime(entryIndex));
|
|
}
|
|
}
|
|
|
|
void Menu::updateTime(uint32 time) {
|
|
if (_currentTime == _time)
|
|
_delta = 0;
|
|
|
|
_currentTime = time;
|
|
|
|
if (_time != time) {
|
|
if (getSoundQueue()->isBuffered(kEntityChapters))
|
|
getSoundQueue()->stop(kEntityChapters);
|
|
|
|
getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", kSoundTypeMenu | kSoundFlagFixedVolume | kVolumeFull, kEntityChapters);
|
|
adjustIndex(_currentTime, _time, false);
|
|
}
|
|
}
|
|
|
|
void Menu::adjustIndex(uint32 time1, uint32 time2, bool searchEntry) {
|
|
uint32 index = 0;
|
|
int32 timeDelta = -1;
|
|
|
|
if (time1 != time2) {
|
|
|
|
index = _index;
|
|
|
|
if (time2 >= time1) {
|
|
if (searchEntry) {
|
|
uint32 currentIndex = _index;
|
|
|
|
if ((int32)_index >= 0) {
|
|
do {
|
|
// Calculate new delta
|
|
int32 newDelta = time1 - (uint32)getSaveLoad()->getTime(currentIndex);
|
|
|
|
if (newDelta >= 0 && timeDelta >= newDelta) {
|
|
timeDelta = newDelta;
|
|
index = currentIndex;
|
|
}
|
|
|
|
--currentIndex;
|
|
} while ((int32)currentIndex >= 0);
|
|
}
|
|
} else {
|
|
index = _index - 1;
|
|
}
|
|
} else {
|
|
if (searchEntry) {
|
|
uint32 currentIndex = _index;
|
|
|
|
if (_lastIndex >= _index) {
|
|
do {
|
|
// Calculate new delta
|
|
int32 newDelta = (uint32)getSaveLoad()->getTime(currentIndex) - time1;
|
|
|
|
if (newDelta >= 0 && timeDelta > newDelta) {
|
|
timeDelta = newDelta;
|
|
index = currentIndex;
|
|
}
|
|
|
|
++currentIndex;
|
|
} while (currentIndex <= _lastIndex);
|
|
}
|
|
} else {
|
|
index = _index + 1;
|
|
}
|
|
}
|
|
|
|
_index = index;
|
|
checkHotspots();
|
|
}
|
|
|
|
if (_index == _currentIndex) {
|
|
if (getProgress().chapter != getSaveLoad()->getChapter(index))
|
|
getProgress().chapter = getSaveLoad()->getChapter(_index);
|
|
}
|
|
}
|
|
|
|
void Menu::goToTime(uint32 time) {
|
|
|
|
uint32 entryIndex = 0;
|
|
uint32 deltaTime = (uint32)ABS((int32)(getSaveLoad()->getTime(0) - time));
|
|
uint32 index = 0;
|
|
|
|
do {
|
|
uint32 deltaTime2 = (uint32)ABS((int32)(getSaveLoad()->getTime(index) - time));
|
|
if (deltaTime2 < deltaTime) {
|
|
deltaTime = deltaTime2;
|
|
entryIndex = index;
|
|
}
|
|
|
|
++index;
|
|
} while (_lastIndex >= index);
|
|
|
|
_currentIndex = entryIndex;
|
|
updateTime(getSaveLoad()->getTime(entryIndex));
|
|
}
|
|
|
|
void Menu::setTime() {
|
|
_currentIndex = _index;
|
|
_currentTime = getSaveLoad()->getTime(_currentIndex);
|
|
|
|
if (_time == _currentTime)
|
|
adjustTime();
|
|
}
|
|
|
|
void Menu::forwardTime() {
|
|
if (_lastIndex <= _index)
|
|
return;
|
|
|
|
_currentIndex = _lastIndex;
|
|
updateTime(getSaveLoad()->getTime(_currentIndex));
|
|
}
|
|
|
|
void Menu::rewindTime() {
|
|
if (!_index)
|
|
return;
|
|
|
|
_currentIndex = 0;
|
|
updateTime(getSaveLoad()->getTime(_currentIndex));
|
|
}
|
|
|
|
void Menu::adjustTime() {
|
|
uint32 originalTime = _time;
|
|
|
|
// Adjust time delta
|
|
Common::Rational timeDelta(_delta >= 90 ? 9 : (9 * _delta + 89), _delta >= 90 ? 1 : 90);
|
|
|
|
if (_currentTime < _time) {
|
|
timeDelta *= 900;
|
|
_time -= (uint)timeDelta.toInt();
|
|
|
|
if (_currentTime > _time)
|
|
_time = _currentTime;
|
|
} else {
|
|
timeDelta *= 900;
|
|
_time += (uint)timeDelta.toInt();
|
|
|
|
if (_currentTime < _time)
|
|
_time = _currentTime;
|
|
}
|
|
|
|
if (_currentTime == _time && getSoundQueue()->isBuffered(kEntityChapters))
|
|
getSoundQueue()->stop(kEntityChapters);
|
|
|
|
_clock->draw(_time);
|
|
_trainLine->draw(_time);
|
|
getScenes()->drawFrames(true);
|
|
|
|
adjustIndex(_time, originalTime, true);
|
|
|
|
++_delta;
|
|
}
|
|
|
|
void Menu::moveToCity(CityButton city, bool clicked) {
|
|
uint32 time = (uint32)_cityButtonsInfo[city].time;
|
|
|
|
// TODO Check if we have access (there seems to be more checks on some internal times) - probably : current_time (menu only) / game time / some other?
|
|
if (_lowerTime < time || _time == time || _currentTime == time) {
|
|
hideOverlays();
|
|
return;
|
|
}
|
|
|
|
// Show city overlay
|
|
showFrame((StartMenuOverlay)((_cityButtonsInfo[city].index >> 6) + 3), _cityButtonsInfo[city].index & 63, true);
|
|
|
|
if (clicked) {
|
|
showFrame(kOverlayTooltip, -1, true);
|
|
getSound()->playSound(kEntityPlayer, "LIB046");
|
|
goToTime(time);
|
|
|
|
_handleTimeDelta = true;
|
|
|
|
return;
|
|
}
|
|
|
|
// Special case of first and last cities
|
|
if (city == kParis || city == kConstantinople) {
|
|
showFrame(kOverlayTooltip, (city == kParis) ? kTooltipRewindParis : kTooltipForwardConstantinople, true);
|
|
return;
|
|
}
|
|
|
|
showFrame(kOverlayTooltip, (_time <= time) ? _cityButtonsInfo[city].forward : _cityButtonsInfo[city].rewind, true);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Sound / Brightness
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Get current volume (converted internal ScummVM value)
|
|
uint32 Menu::getVolume() const {
|
|
return getState()->volume;
|
|
}
|
|
|
|
// Set the volume (converts to ScummVM values)
|
|
void Menu::setVolume(uint32 volume) const {
|
|
getState()->volume = volume;
|
|
|
|
// Clamp volume
|
|
uint32 value = volume * Audio::Mixer::kMaxMixerVolume / 7;
|
|
|
|
if (value > Audio::Mixer::kMaxMixerVolume)
|
|
value = Audio::Mixer::kMaxMixerVolume;
|
|
|
|
_engine->_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, (int32)value);
|
|
}
|
|
|
|
uint32 Menu::getBrightness() const {
|
|
return getState()->brightness;
|
|
}
|
|
|
|
void Menu::setBrightness(uint32 brightness) const {
|
|
getState()->brightness = brightness;
|
|
|
|
// TODO reload cursor & font with adjusted brightness
|
|
}
|
|
|
|
} // End of namespace LastExpress
|