[Scummvm-cvs-logs] scummvm master -> 712af61f76148095cd3b8762eeb2b2b10502df1f

Littleboy littleboy22 at gmail.com
Thu Jun 23 15:00:01 CEST 2011


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
f0cf72f431 LASTEXPRESS: Move Menu class to a separate folder
7a96e0bfb6 LASTEXPRESS: Extract Clock and TrainLine classes to separate files
b694a78f62 ANALYSIS: Add static casts to is* functions
712af61f76 BACKENDS: Silence warnings when compiling Win32TaskbarManager with mingw and add CLSID_ShellLink definition


Commit: f0cf72f4313c146dcec25fa004312a4319b89b91
    https://github.com/scummvm/scummvm/commit/f0cf72f4313c146dcec25fa004312a4319b89b91
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-23T03:58:21-07:00

Commit Message:
LASTEXPRESS: Move Menu class to a separate folder

Changed paths:
  A engines/lastexpress/menu/menu.cpp
  A engines/lastexpress/menu/menu.h
  R engines/lastexpress/game/menu.cpp
  R engines/lastexpress/game/menu.h
    engines/lastexpress/entities/chapters.cpp
    engines/lastexpress/game/inventory.cpp
    engines/lastexpress/game/logic.cpp
    engines/lastexpress/game/savegame.cpp
    engines/lastexpress/lastexpress.cpp
    engines/lastexpress/module.mk



diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index 1252a62..6a41590 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -57,13 +57,14 @@
 #include "lastexpress/game/entities.h"
 #include "lastexpress/game/inventory.h"
 #include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/menu/menu.h"
+
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/resource.h"
diff --git a/engines/lastexpress/game/inventory.cpp b/engines/lastexpress/game/inventory.cpp
index adf6ff7..07ad8d9 100644
--- a/engines/lastexpress/game/inventory.cpp
+++ b/engines/lastexpress/game/inventory.cpp
@@ -27,11 +27,12 @@
 #include "lastexpress/data/snd.h"
 
 #include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/menu/menu.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/game/logic.cpp b/engines/lastexpress/game/logic.cpp
index a8a2ce8..3bd7d6d 100644
--- a/engines/lastexpress/game/logic.cpp
+++ b/engines/lastexpress/game/logic.cpp
@@ -38,7 +38,6 @@
 #include "lastexpress/game/beetle.h"
 #include "lastexpress/game/entities.h"
 #include "lastexpress/game/inventory.h"
-#include "lastexpress/game/menu.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savegame.h"
 #include "lastexpress/game/savepoint.h"
@@ -46,6 +45,8 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/menu/menu.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
diff --git a/engines/lastexpress/game/menu.cpp b/engines/lastexpress/game/menu.cpp
deleted file mode 100644
index 27a43d8..0000000
--- a/engines/lastexpress/game/menu.cpp
+++ /dev/null
@@ -1,1542 +0,0 @@
-/* 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 "lastexpress/game/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/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/sound.h"
-#include "lastexpress/game/state.h"
-
-#include "lastexpress/graphics.h"
-#include "lastexpress/helpers.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
-//////////////////////////////////////////////////////////////////////////
-
-// Information about the cities on the train line
-static const struct {
-	uint8 frame;
-	TimeValue time;
-} _trainCities[31] = {
-	{0, kTimeCityParis},
-	{9, kTimeCityEpernay},
-	{11, kTimeCityChalons},
-	{16, kTimeCityBarLeDuc},
-	{21, kTimeCityNancy},
-	{25, kTimeCityLuneville},
-	{35, kTimeCityAvricourt},
-	{37, kTimeCityDeutschAvricourt},
-	{40, kTimeCityStrasbourg},
-	{53, kTimeCityBadenOos},
-	{56, kTimeCityKarlsruhe},
-	{60, kTimeCityStuttgart},
-	{63, kTimeCityGeislingen},
-	{66, kTimeCityUlm},
-	{68, kTimeCityAugsburg},
-	{73, kTimeCityMunich},
-	{84, kTimeCitySalzbourg},
-	{89, kTimeCityAttnangPuchheim},
-	{97, kTimeCityWels},
-	{100, kTimeCityLinz},
-	{104, kTimeCityAmstetten},
-	{111, kTimeCityVienna},
-	{120, kTimeCityPoszony},
-	{124, kTimeCityGalanta},
-	{132, kTimeCityBudapest},
-	{148, kTimeCityBelgrade},
-	/* Line 1 ends at 150 - line 2 begins at 0 */
-	{157, kTimeCityNish},
-	{165, kTimeCityTzaribrod},
-	{174, kTimeCitySofia},
-	{198, kTimeCityAdrianople},
-	{210, kTimeCityConstantinople}};
-
-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}
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Clock
-//////////////////////////////////////////////////////////////////////////
-class Clock {
-public:
-	explicit Clock(LastExpressEngine *engine);
-	~Clock();
-
-	void draw(uint32 time);
-	void clear();
-
-private:
-	LastExpressEngine *_engine;
-
-	// Frames
-	SequenceFrame *_frameMinutes;
-	SequenceFrame *_frameHour;
-	SequenceFrame *_frameSun;
-	SequenceFrame *_frameDate;
-};
-
-Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
-	_frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
-	_frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
-	_frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
-	_frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
-}
-
-Clock::~Clock() {
-	SAFE_DELETE(_frameMinutes);
-	SAFE_DELETE(_frameHour);
-	SAFE_DELETE(_frameSun);
-	SAFE_DELETE(_frameDate);
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-void Clock::clear() {
-	getScenes()->removeFromQueue(_frameMinutes);
-	getScenes()->removeFromQueue(_frameHour);
-	getScenes()->removeFromQueue(_frameSun);
-	getScenes()->removeFromQueue(_frameDate);
-}
-
-void Clock::draw(uint32 time) {
-	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
-	// Check that sequences have been loaded
-	if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
-		error("Clock::process: clock sequences have not been loaded correctly!");
-
-	// Clear existing frames
-	clear();
-
-	// Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
-	// Game ends at:   4941000 = 7:30 p.m. on July 26, 1914
-	// Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
-
-	// 15 = 1 second
-	// 15 * 60 = 900 = 1 minute
-	// 900 * 60 = 54000 = 1 hour
-	// 54000 * 24 = 1296000 = 1 day
-
-	// Calculate each sequence index from the current time
-
-	uint8 hour = 0;
-	uint8 minute = 0;
-	State::getHourMinutes(time, &hour, &minute);
-	uint32 index_date = 18 * time / 1296000;
-	if (hour == 23)
-		index_date += 18 * minute / 60;
-
-	// Set sequences frames
-	_frameMinutes->setFrame(minute);
-	_frameHour->setFrame((5 * hour + minute / 12) % 60);
-	_frameSun->setFrame((5 * hour + minute / 12) % 120);
-	_frameDate->setFrame((uint16)index_date);
-
-	// Adjust z-order and queue
-	_frameMinutes->getInfo()->location = 1;
-	_frameHour->getInfo()->location = 1;
-	_frameSun->getInfo()->location = 1;
-	_frameDate->getInfo()->location = 1;
-
-	getScenes()->addToQueue(_frameMinutes);
-	getScenes()->addToQueue(_frameHour);
-	getScenes()->addToQueue(_frameSun);
-	getScenes()->addToQueue(_frameDate);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// TrainLine
-//////////////////////////////////////////////////////////////////////////
-class TrainLine {
-public:
-	explicit TrainLine(LastExpressEngine *engine);
-	~TrainLine();
-
-	void draw(uint32 time);
-	void clear();
-
-private:
-	LastExpressEngine *_engine;
-
-	// Frames
-	SequenceFrame *_frameLine1;
-	SequenceFrame *_frameLine2;
-};
-
-TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
-	_frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
-	_frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
-}
-
-TrainLine::~TrainLine() {
-	SAFE_DELETE(_frameLine1);
-	SAFE_DELETE(_frameLine2);
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-void TrainLine::clear() {
-	getScenes()->removeFromQueue(_frameLine1);
-	getScenes()->removeFromQueue(_frameLine2);
-}
-
-// Draw the train line at the time
-//  line1: 150 frames (=> Belgrade)
-//  line2: 61 frames (=> Constantinople)
-void TrainLine::draw(uint32 time) {
-	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
-	// Check that sequences have been loaded
-	if (!_frameLine1 || !_frameLine2)
-		error("TrainLine::process: Line sequences have not been loaded correctly!");
-
-	// Clear existing frames
-	clear();
-
-	// Get the index of the last city the train has visited
-	uint index = 0;
-	for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
-		if ((uint32)_trainCities[i].time <= time)
-			index = i;
-
-	uint16 frame;
-	if (time > (uint32)_trainCities[index].time) {
-		// Interpolate linearly to use a frame between the cities
-		uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
-		uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
-		uint traveledTime = (time - (uint)_trainCities[index].time);
-		frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
-	} else {
-		// Exactly on the city
-		frame = _trainCities[index].frame;
-	}
-
-	// Set frame, z-order and queue
-	if (frame < 150) {
-		_frameLine1->setFrame(frame);
-
-		_frameLine1->getInfo()->location = 1;
-		getScenes()->addToQueue(_frameLine1);
-	} else {
-		// We passed Belgrade
-		_frameLine1->setFrame(149);
-		_frameLine2->setFrame(frame - 150);
-
-		_frameLine1->getInfo()->location = 1;
-		_frameLine2->getInfo()->location = 1;
-
-		getScenes()->addToQueue(_frameLine1);
-		getScenes()->addToQueue(_frameLine2);
-	}
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// Menu
-//////////////////////////////////////////////////////////////////////////
-Menu::Menu(LastExpressEngine *engine) : _engine(engine),
-	_seqTooltips(NULL), _seqEggButtons(NULL), _seqButtons(NULL), _seqAcorn(NULL), _seqCity1(NULL), _seqCity2(NULL), _seqCity3(NULL), _seqCredits(NULL),
-	_gameId(kGameBlue), _hasShownStartScreen(false), _hasShownIntro(false),
-	_isShowingCredits(false), _isGameStarted(false), _isShowingMenu(false),
-	_creditsSequenceIndex(0), _checkHotspotsTicks(15),  _mouseFlags(Common::EVENT_INVALID), _lastHotspot(NULL),
-	_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 = NULL;
-
-	// Cleanup frames
-	for (MenuFrames::iterator it = _frames.begin(); it != _frames.end(); it++)
-		SAFE_DELETE(it->_value);
-
-	_frames.clear();
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// 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 = NULL;
-		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", SoundManager::kFlagMusic, 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", SoundManager::kFlagMusic, 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;
-
-					getSound()->updateQueue();
-				}
-			}
-		}
-	}
-
-	_hasShownStartScreen = true;
-
-	// Init Menu
-	init(doSavegame, type, value);
-
-	// Setup sound
-	getSound()->unknownFunction4();
-	getSound()->resetQueue(SoundManager::kSoundType11, SoundManager::kSoundType13);
-	if (getSound()->isBuffered("TIMER"))
-		getSound()->removeFromQueue("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);
-
-			getSound()->clearStatus();
-			getSound()->updateQueue();
-			getSound()->playSound(kEntityPlayer, "LIB046");
-
-			// FIXME uncomment when sound queue is properly implemented
-			/*while (getSound()->isBuffered("LIB046"))
-				getSound()->updateQueue();*/
-
-			getFlags()->shouldRedraw = false;
-
-			Engine::quitGame();
-
-			return false;
-		} else {
-			showFrame(kOverlayButtons, kButtonQuit, true);
-		}
-		break;
-
-	//////////////////////////////////////////////////////////////////////////
-	case kMenuCase4:
-		if (clicked)
-			_index = 0;
-		// fall down to kMenuContinue
-
-	//////////////////////////////////////////////////////////////////////////
-	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) {
-			getSound()->processEntry(SoundManager::kSoundType11);
-		} 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) {
-							getSound()->processEntry(SoundManager::kSoundType11);
-
-							// Show intro
-							Animation animation;
-							if (animation.load(getArchive("1601.nis")))
-								animation.play();
-
-							getEvent(kEventIntro) = 1;
-						}
-					}
-				}
-			}
-
-			if (!getEvent(kEventIntro))	{
-				getEvent(kEventIntro) = 1;
-
-				getSound()->processEntry(SoundManager::kSoundType11);
-			}
-		}
-
-		// 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();
-
-				getSound()->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();
-
-				getSound()->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 {
-		// TODO rename saves?
-	}
-
-	// Create a new savegame if needed
-	if (!SaveLoad::isSavegamePresent(_gameId))
-		getSaveLoad()->create(_gameId);
-
-	if (doSavegame)
-		getSaveLoad()->saveGame(kSavegameTypeEvent2, kEntityPlayer, kEventNone);
-
-	if (!getGlobalTimer()) {
-		// TODO: remove existing savegame temp file
-	}
-
-	// 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()->loadGame(_gameId);
-		} else {
-			getLogic()->resetState();
-			getEntities()->setup(true, kEntityPlayer);
-		}
-	} else {
-		getSaveLoad()->loadGame(_gameId, _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 = NULL;
-	getScenes()->get(getState()->scene)->checkHotSpot(getCoords(), &hotspot);
-
-	if (hotspot)
-		handleEvent((StartMenuAction)hotspot->action, _mouseFlags);
-	else
-		hideOverlays();
-}
-
-void Menu::hideOverlays() {
-	_lastHotspot = NULL;
-
-	// 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 (getSound()->isBuffered(kEntityChapters))
-			getSound()->removeFromQueue(kEntityChapters);
-
-		getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", SoundManager::kFlagMenuClock, 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 && getSound()->isBuffered(kEntityChapters))
-		getSound()->removeFromQueue(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
diff --git a/engines/lastexpress/game/menu.h b/engines/lastexpress/game/menu.h
deleted file mode 100644
index 4b84c06..0000000
--- a/engines/lastexpress/game/menu.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/* 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 LASTEXPRESS_MENU_H
-#define LASTEXPRESS_MENU_H
-
-#include "lastexpress/data/sequence.h"
-
-#include "lastexpress/eventhandler.h"
-
-#include "lastexpress/shared.h"
-
-#include "common/hashmap.h"
-
-namespace LastExpress {
-
-class LastExpressEngine;
-class Scene;
-class SceneHotspot;
-
-class Clock;
-class TrainLine;
-
-class Menu : public EventHandler {
-public:
-	Menu(LastExpressEngine *engine);
-	~Menu();
-
-	void show(bool doSavegame, SavegameType type, uint32 value);
-
-	// Event handling
-	void eventMouse(const Common::Event &ev);
-	void eventTick(const Common::Event &ev);
-
-	bool isShown() const { return _isShowingMenu; }
-
-	GameId getGameId() const { return _gameId; }
-
-private:
-	// Start menu events
-	enum StartMenuAction {
-		kMenuContinue = 1,
-		kMenuCredits = 2,
-		kMenuQuitGame = 3,
-		kMenuCase4 = 4,
-		kMenuSwitchSaveGame = 6,
-		kMenuRewindGame = 7,
-		kMenuForwardGame = 8,
-		kMenuParis = 10,
-		kMenuStrasBourg = 11,
-		kMenuMunich = 12,
-		kMenuVienna = 13,
-		kMenuBudapest = 14,
-		kMenuBelgrade = 15,
-		kMenuConstantinople = 16,
-		kMenuDecreaseVolume = 17,
-		kMenuIncreaseVolume = 18,
-		kMenuDecreaseBrightness = 19,
-		kMenuIncreaseBrightness = 20
-	};
-
-	// City buttons
-	enum CityButton {
-		kParis = 0,
-		kStrasbourg = 1,
-		kMunich = 2,
-		kVienna = 3,
-		kBudapest = 4,
-		kBelgrade = 5,
-		kConstantinople = 6
-	};
-
-	// Start menu overlay elements
-	enum StartMenuOverlay {
-		kOverlayTooltip,            // 0
-		kOverlayEggButtons,
-		kOverlayButtons,
-		kOverlayAcorn,
-		kOverlayCity1,
-		kOverlayCity2,              // 5
-		kOverlayCity3,
-		kOverlayCredits
-	};
-
-	LastExpressEngine *_engine;
-
-	// Sequences
-	Sequence *_seqTooltips;
-	Sequence *_seqEggButtons;
-	Sequence *_seqButtons;
-	Sequence *_seqAcorn;
-	Sequence *_seqCity1;
-	Sequence *_seqCity2;
-	Sequence *_seqCity3;
-	Sequence *_seqCredits;
-
-	GameId _gameId;
-
-	// Indicator to know if we need to show the start animation when showMenu is called
-	bool _hasShownStartScreen;
-	bool _hasShownIntro;
-
-	bool _isShowingCredits;
-	bool _isGameStarted;
-	bool _isShowingMenu;
-
-
-	uint16 _creditsSequenceIndex;
-
-	//////////////////////////////////////////////////////////////////////////
-	// Event handling
-	uint32 _checkHotspotsTicks;
-	Common::EventType _mouseFlags;
-	SceneHotspot *_lastHotspot;
-
-	void init(bool doSavegame, SavegameType type, uint32 value);
-	void setup();
-	bool handleEvent(StartMenuAction action, Common::EventType type);
-	void checkHotspots();
-	void setLogicEventHandlers();
-
-	//////////////////////////////////////////////////////////////////////////
-	// Game-related
-	void startGame();
-	void switchGame();
-
-	//////////////////////////////////////////////////////////////////////////
-	// Overlays & elements
-	Clock *_clock;
-	TrainLine *_trainLine;
-
-	struct MenuOverlays_EqualTo {
-		bool operator()(const StartMenuOverlay &x, const StartMenuOverlay &y) const { return x == y; }
-	};
-
-	struct MenuOverlays_Hash {
-		uint operator()(const StartMenuOverlay &x) const { return x; }
-	};
-
-	typedef Common::HashMap<StartMenuOverlay, SequenceFrame *, MenuOverlays_Hash, MenuOverlays_EqualTo> MenuFrames;
-
-	MenuFrames _frames;
-
-	void hideOverlays();
-	void showFrame(StartMenuOverlay overlay, int index, bool redraw);
-
-	void clear();
-
-	// TODO: remove?
-	void moveToCity(CityButton city, bool clicked);
-
-	//////////////////////////////////////////////////////////////////////////
-	// Misc
-	Common::String getAcornSequenceName(GameId id) const;
-
-	//////////////////////////////////////////////////////////////////////////
-	// Time
-	uint32 _currentTime;  // current game time
-	uint32 _lowerTime;    // lower time value
-	uint32 _time;
-
-	uint32 _currentIndex; // current savegame entry
-	uint32 _index;
-	uint32 _lastIndex;
-	uint32 _delta;
-	bool _handleTimeDelta;
-
-	void initTime(SavegameType type, uint32 val);
-	void updateTime(uint32 time);
-	void adjustTime();
-	void adjustIndex(uint32 time1, uint32 time2, bool searchEntry);
-	void goToTime(uint32 time);
-	void setTime();
-	void forwardTime();
-	void rewindTime();
-	bool hasTimeDelta() { return (_currentTime - _time) >= 1; }
-
-	//////////////////////////////////////////////////////////////////////////
-	// Sound/Brightness related
-	uint32 getVolume() const;
-	void setVolume(uint32 volume) const;
-	uint32 getBrightness() const;
-	void setBrightness(uint32 brightness) const;
-};
-
-} // End of namespace LastExpress
-
-#endif // LASTEXPRESS_MENU_H
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 5d06eca..594cd12 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -24,11 +24,12 @@
 
 #include "lastexpress/game/inventory.h"
 #include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/menu/menu.h"
+
 #include "lastexpress/debug.h"
 #include "lastexpress/lastexpress.h"
 #include "lastexpress/helpers.h"
diff --git a/engines/lastexpress/lastexpress.cpp b/engines/lastexpress/lastexpress.cpp
index 120e6eb..73893c9 100644
--- a/engines/lastexpress/lastexpress.cpp
+++ b/engines/lastexpress/lastexpress.cpp
@@ -26,11 +26,12 @@
 #include "lastexpress/data/font.h"
 
 #include "lastexpress/game/logic.h"
-#include "lastexpress/game/menu.h"
 #include "lastexpress/game/scenes.h"
 #include "lastexpress/game/state.h"
 #include "lastexpress/game/sound.h"
 
+#include "lastexpress/menu/menu.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/resource.h"
diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp
new file mode 100644
index 0000000..b7e6a14
--- /dev/null
+++ b/engines/lastexpress/menu/menu.cpp
@@ -0,0 +1,1542 @@
+/* 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 "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/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/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/graphics.h"
+#include "lastexpress/helpers.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
+//////////////////////////////////////////////////////////////////////////
+
+// Information about the cities on the train line
+static const struct {
+	uint8 frame;
+	TimeValue time;
+} _trainCities[31] = {
+	{0, kTimeCityParis},
+	{9, kTimeCityEpernay},
+	{11, kTimeCityChalons},
+	{16, kTimeCityBarLeDuc},
+	{21, kTimeCityNancy},
+	{25, kTimeCityLuneville},
+	{35, kTimeCityAvricourt},
+	{37, kTimeCityDeutschAvricourt},
+	{40, kTimeCityStrasbourg},
+	{53, kTimeCityBadenOos},
+	{56, kTimeCityKarlsruhe},
+	{60, kTimeCityStuttgart},
+	{63, kTimeCityGeislingen},
+	{66, kTimeCityUlm},
+	{68, kTimeCityAugsburg},
+	{73, kTimeCityMunich},
+	{84, kTimeCitySalzbourg},
+	{89, kTimeCityAttnangPuchheim},
+	{97, kTimeCityWels},
+	{100, kTimeCityLinz},
+	{104, kTimeCityAmstetten},
+	{111, kTimeCityVienna},
+	{120, kTimeCityPoszony},
+	{124, kTimeCityGalanta},
+	{132, kTimeCityBudapest},
+	{148, kTimeCityBelgrade},
+	/* Line 1 ends at 150 - line 2 begins at 0 */
+	{157, kTimeCityNish},
+	{165, kTimeCityTzaribrod},
+	{174, kTimeCitySofia},
+	{198, kTimeCityAdrianople},
+	{210, kTimeCityConstantinople}};
+
+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}
+};
+
+//////////////////////////////////////////////////////////////////////////
+// Clock
+//////////////////////////////////////////////////////////////////////////
+class Clock {
+public:
+	explicit Clock(LastExpressEngine *engine);
+	~Clock();
+
+	void draw(uint32 time);
+	void clear();
+
+private:
+	LastExpressEngine *_engine;
+
+	// Frames
+	SequenceFrame *_frameMinutes;
+	SequenceFrame *_frameHour;
+	SequenceFrame *_frameSun;
+	SequenceFrame *_frameDate;
+};
+
+Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
+	_frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
+	_frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
+	_frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
+	_frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
+}
+
+Clock::~Clock() {
+	SAFE_DELETE(_frameMinutes);
+	SAFE_DELETE(_frameHour);
+	SAFE_DELETE(_frameSun);
+	SAFE_DELETE(_frameDate);
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+void Clock::clear() {
+	getScenes()->removeFromQueue(_frameMinutes);
+	getScenes()->removeFromQueue(_frameHour);
+	getScenes()->removeFromQueue(_frameSun);
+	getScenes()->removeFromQueue(_frameDate);
+}
+
+void Clock::draw(uint32 time) {
+	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+	// Check that sequences have been loaded
+	if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
+		error("Clock::process: clock sequences have not been loaded correctly!");
+
+	// Clear existing frames
+	clear();
+
+	// Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
+	// Game ends at:   4941000 = 7:30 p.m. on July 26, 1914
+	// Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
+
+	// 15 = 1 second
+	// 15 * 60 = 900 = 1 minute
+	// 900 * 60 = 54000 = 1 hour
+	// 54000 * 24 = 1296000 = 1 day
+
+	// Calculate each sequence index from the current time
+
+	uint8 hour = 0;
+	uint8 minute = 0;
+	State::getHourMinutes(time, &hour, &minute);
+	uint32 index_date = 18 * time / 1296000;
+	if (hour == 23)
+		index_date += 18 * minute / 60;
+
+	// Set sequences frames
+	_frameMinutes->setFrame(minute);
+	_frameHour->setFrame((5 * hour + minute / 12) % 60);
+	_frameSun->setFrame((5 * hour + minute / 12) % 120);
+	_frameDate->setFrame((uint16)index_date);
+
+	// Adjust z-order and queue
+	_frameMinutes->getInfo()->location = 1;
+	_frameHour->getInfo()->location = 1;
+	_frameSun->getInfo()->location = 1;
+	_frameDate->getInfo()->location = 1;
+
+	getScenes()->addToQueue(_frameMinutes);
+	getScenes()->addToQueue(_frameHour);
+	getScenes()->addToQueue(_frameSun);
+	getScenes()->addToQueue(_frameDate);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// TrainLine
+//////////////////////////////////////////////////////////////////////////
+class TrainLine {
+public:
+	explicit TrainLine(LastExpressEngine *engine);
+	~TrainLine();
+
+	void draw(uint32 time);
+	void clear();
+
+private:
+	LastExpressEngine *_engine;
+
+	// Frames
+	SequenceFrame *_frameLine1;
+	SequenceFrame *_frameLine2;
+};
+
+TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
+	_frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
+	_frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
+}
+
+TrainLine::~TrainLine() {
+	SAFE_DELETE(_frameLine1);
+	SAFE_DELETE(_frameLine2);
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+void TrainLine::clear() {
+	getScenes()->removeFromQueue(_frameLine1);
+	getScenes()->removeFromQueue(_frameLine2);
+}
+
+// Draw the train line at the time
+//  line1: 150 frames (=> Belgrade)
+//  line2: 61 frames (=> Constantinople)
+void TrainLine::draw(uint32 time) {
+	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+	// Check that sequences have been loaded
+	if (!_frameLine1 || !_frameLine2)
+		error("TrainLine::process: Line sequences have not been loaded correctly!");
+
+	// Clear existing frames
+	clear();
+
+	// Get the index of the last city the train has visited
+	uint index = 0;
+	for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
+		if ((uint32)_trainCities[i].time <= time)
+			index = i;
+
+	uint16 frame;
+	if (time > (uint32)_trainCities[index].time) {
+		// Interpolate linearly to use a frame between the cities
+		uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
+		uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
+		uint traveledTime = (time - (uint)_trainCities[index].time);
+		frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
+	} else {
+		// Exactly on the city
+		frame = _trainCities[index].frame;
+	}
+
+	// Set frame, z-order and queue
+	if (frame < 150) {
+		_frameLine1->setFrame(frame);
+
+		_frameLine1->getInfo()->location = 1;
+		getScenes()->addToQueue(_frameLine1);
+	} else {
+		// We passed Belgrade
+		_frameLine1->setFrame(149);
+		_frameLine2->setFrame(frame - 150);
+
+		_frameLine1->getInfo()->location = 1;
+		_frameLine2->getInfo()->location = 1;
+
+		getScenes()->addToQueue(_frameLine1);
+		getScenes()->addToQueue(_frameLine2);
+	}
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Menu
+//////////////////////////////////////////////////////////////////////////
+Menu::Menu(LastExpressEngine *engine) : _engine(engine),
+	_seqTooltips(NULL), _seqEggButtons(NULL), _seqButtons(NULL), _seqAcorn(NULL), _seqCity1(NULL), _seqCity2(NULL), _seqCity3(NULL), _seqCredits(NULL),
+	_gameId(kGameBlue), _hasShownStartScreen(false), _hasShownIntro(false),
+	_isShowingCredits(false), _isGameStarted(false), _isShowingMenu(false),
+	_creditsSequenceIndex(0), _checkHotspotsTicks(15),  _mouseFlags(Common::EVENT_INVALID), _lastHotspot(NULL),
+	_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 = NULL;
+
+	// Cleanup frames
+	for (MenuFrames::iterator it = _frames.begin(); it != _frames.end(); it++)
+		SAFE_DELETE(it->_value);
+
+	_frames.clear();
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// 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 = NULL;
+		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", SoundManager::kFlagMusic, 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", SoundManager::kFlagMusic, 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;
+
+					getSound()->updateQueue();
+				}
+			}
+		}
+	}
+
+	_hasShownStartScreen = true;
+
+	// Init Menu
+	init(doSavegame, type, value);
+
+	// Setup sound
+	getSound()->unknownFunction4();
+	getSound()->resetQueue(SoundManager::kSoundType11, SoundManager::kSoundType13);
+	if (getSound()->isBuffered("TIMER"))
+		getSound()->removeFromQueue("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);
+
+			getSound()->clearStatus();
+			getSound()->updateQueue();
+			getSound()->playSound(kEntityPlayer, "LIB046");
+
+			// FIXME uncomment when sound queue is properly implemented
+			/*while (getSound()->isBuffered("LIB046"))
+				getSound()->updateQueue();*/
+
+			getFlags()->shouldRedraw = false;
+
+			Engine::quitGame();
+
+			return false;
+		} else {
+			showFrame(kOverlayButtons, kButtonQuit, true);
+		}
+		break;
+
+	//////////////////////////////////////////////////////////////////////////
+	case kMenuCase4:
+		if (clicked)
+			_index = 0;
+		// fall down to kMenuContinue
+
+	//////////////////////////////////////////////////////////////////////////
+	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) {
+			getSound()->processEntry(SoundManager::kSoundType11);
+		} 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) {
+							getSound()->processEntry(SoundManager::kSoundType11);
+
+							// Show intro
+							Animation animation;
+							if (animation.load(getArchive("1601.nis")))
+								animation.play();
+
+							getEvent(kEventIntro) = 1;
+						}
+					}
+				}
+			}
+
+			if (!getEvent(kEventIntro))	{
+				getEvent(kEventIntro) = 1;
+
+				getSound()->processEntry(SoundManager::kSoundType11);
+			}
+		}
+
+		// 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();
+
+				getSound()->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();
+
+				getSound()->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 {
+		// TODO rename saves?
+	}
+
+	// Create a new savegame if needed
+	if (!SaveLoad::isSavegamePresent(_gameId))
+		getSaveLoad()->create(_gameId);
+
+	if (doSavegame)
+		getSaveLoad()->saveGame(kSavegameTypeEvent2, kEntityPlayer, kEventNone);
+
+	if (!getGlobalTimer()) {
+		// TODO: remove existing savegame temp file
+	}
+
+	// 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()->loadGame(_gameId);
+		} else {
+			getLogic()->resetState();
+			getEntities()->setup(true, kEntityPlayer);
+		}
+	} else {
+		getSaveLoad()->loadGame(_gameId, _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 = NULL;
+	getScenes()->get(getState()->scene)->checkHotSpot(getCoords(), &hotspot);
+
+	if (hotspot)
+		handleEvent((StartMenuAction)hotspot->action, _mouseFlags);
+	else
+		hideOverlays();
+}
+
+void Menu::hideOverlays() {
+	_lastHotspot = NULL;
+
+	// 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 (getSound()->isBuffered(kEntityChapters))
+			getSound()->removeFromQueue(kEntityChapters);
+
+		getSound()->playSoundWithSubtitles((_currentTime >= _time) ? "LIB042" : "LIB041", SoundManager::kFlagMenuClock, 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 && getSound()->isBuffered(kEntityChapters))
+		getSound()->removeFromQueue(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
diff --git a/engines/lastexpress/menu/menu.h b/engines/lastexpress/menu/menu.h
new file mode 100644
index 0000000..4b84c06
--- /dev/null
+++ b/engines/lastexpress/menu/menu.h
@@ -0,0 +1,207 @@
+/* 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 LASTEXPRESS_MENU_H
+#define LASTEXPRESS_MENU_H
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/eventhandler.h"
+
+#include "lastexpress/shared.h"
+
+#include "common/hashmap.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class Scene;
+class SceneHotspot;
+
+class Clock;
+class TrainLine;
+
+class Menu : public EventHandler {
+public:
+	Menu(LastExpressEngine *engine);
+	~Menu();
+
+	void show(bool doSavegame, SavegameType type, uint32 value);
+
+	// Event handling
+	void eventMouse(const Common::Event &ev);
+	void eventTick(const Common::Event &ev);
+
+	bool isShown() const { return _isShowingMenu; }
+
+	GameId getGameId() const { return _gameId; }
+
+private:
+	// Start menu events
+	enum StartMenuAction {
+		kMenuContinue = 1,
+		kMenuCredits = 2,
+		kMenuQuitGame = 3,
+		kMenuCase4 = 4,
+		kMenuSwitchSaveGame = 6,
+		kMenuRewindGame = 7,
+		kMenuForwardGame = 8,
+		kMenuParis = 10,
+		kMenuStrasBourg = 11,
+		kMenuMunich = 12,
+		kMenuVienna = 13,
+		kMenuBudapest = 14,
+		kMenuBelgrade = 15,
+		kMenuConstantinople = 16,
+		kMenuDecreaseVolume = 17,
+		kMenuIncreaseVolume = 18,
+		kMenuDecreaseBrightness = 19,
+		kMenuIncreaseBrightness = 20
+	};
+
+	// City buttons
+	enum CityButton {
+		kParis = 0,
+		kStrasbourg = 1,
+		kMunich = 2,
+		kVienna = 3,
+		kBudapest = 4,
+		kBelgrade = 5,
+		kConstantinople = 6
+	};
+
+	// Start menu overlay elements
+	enum StartMenuOverlay {
+		kOverlayTooltip,            // 0
+		kOverlayEggButtons,
+		kOverlayButtons,
+		kOverlayAcorn,
+		kOverlayCity1,
+		kOverlayCity2,              // 5
+		kOverlayCity3,
+		kOverlayCredits
+	};
+
+	LastExpressEngine *_engine;
+
+	// Sequences
+	Sequence *_seqTooltips;
+	Sequence *_seqEggButtons;
+	Sequence *_seqButtons;
+	Sequence *_seqAcorn;
+	Sequence *_seqCity1;
+	Sequence *_seqCity2;
+	Sequence *_seqCity3;
+	Sequence *_seqCredits;
+
+	GameId _gameId;
+
+	// Indicator to know if we need to show the start animation when showMenu is called
+	bool _hasShownStartScreen;
+	bool _hasShownIntro;
+
+	bool _isShowingCredits;
+	bool _isGameStarted;
+	bool _isShowingMenu;
+
+
+	uint16 _creditsSequenceIndex;
+
+	//////////////////////////////////////////////////////////////////////////
+	// Event handling
+	uint32 _checkHotspotsTicks;
+	Common::EventType _mouseFlags;
+	SceneHotspot *_lastHotspot;
+
+	void init(bool doSavegame, SavegameType type, uint32 value);
+	void setup();
+	bool handleEvent(StartMenuAction action, Common::EventType type);
+	void checkHotspots();
+	void setLogicEventHandlers();
+
+	//////////////////////////////////////////////////////////////////////////
+	// Game-related
+	void startGame();
+	void switchGame();
+
+	//////////////////////////////////////////////////////////////////////////
+	// Overlays & elements
+	Clock *_clock;
+	TrainLine *_trainLine;
+
+	struct MenuOverlays_EqualTo {
+		bool operator()(const StartMenuOverlay &x, const StartMenuOverlay &y) const { return x == y; }
+	};
+
+	struct MenuOverlays_Hash {
+		uint operator()(const StartMenuOverlay &x) const { return x; }
+	};
+
+	typedef Common::HashMap<StartMenuOverlay, SequenceFrame *, MenuOverlays_Hash, MenuOverlays_EqualTo> MenuFrames;
+
+	MenuFrames _frames;
+
+	void hideOverlays();
+	void showFrame(StartMenuOverlay overlay, int index, bool redraw);
+
+	void clear();
+
+	// TODO: remove?
+	void moveToCity(CityButton city, bool clicked);
+
+	//////////////////////////////////////////////////////////////////////////
+	// Misc
+	Common::String getAcornSequenceName(GameId id) const;
+
+	//////////////////////////////////////////////////////////////////////////
+	// Time
+	uint32 _currentTime;  // current game time
+	uint32 _lowerTime;    // lower time value
+	uint32 _time;
+
+	uint32 _currentIndex; // current savegame entry
+	uint32 _index;
+	uint32 _lastIndex;
+	uint32 _delta;
+	bool _handleTimeDelta;
+
+	void initTime(SavegameType type, uint32 val);
+	void updateTime(uint32 time);
+	void adjustTime();
+	void adjustIndex(uint32 time1, uint32 time2, bool searchEntry);
+	void goToTime(uint32 time);
+	void setTime();
+	void forwardTime();
+	void rewindTime();
+	bool hasTimeDelta() { return (_currentTime - _time) >= 1; }
+
+	//////////////////////////////////////////////////////////////////////////
+	// Sound/Brightness related
+	uint32 getVolume() const;
+	void setVolume(uint32 volume) const;
+	uint32 getBrightness() const;
+	void setBrightness(uint32 brightness) const;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_MENU_H
diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk
index e811519..e38772a 100644
--- a/engines/lastexpress/module.mk
+++ b/engines/lastexpress/module.mk
@@ -57,13 +57,13 @@ MODULE_OBJS := \
 	game/entities.o \
 	game/inventory.o \
 	game/logic.o \
-	game/menu.o \
 	game/object.o \
 	game/savegame.o \
 	game/savepoint.o \
 	game/scenes.o \
 	game/sound.o \
 	game/state.o \
+	menu/menu.o \
 	debug.o \
 	detection.o \
 	graphics.o \


Commit: 7a96e0bfb67e9b5b8c0aa9bdae8415fb98214c3f
    https://github.com/scummvm/scummvm/commit/7a96e0bfb67e9b5b8c0aa9bdae8415fb98214c3f
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-23T05:52:45-07:00

Commit Message:
LASTEXPRESS: Extract Clock and TrainLine classes to separate files

Changed paths:
  A engines/lastexpress/menu/clock.cpp
  A engines/lastexpress/menu/clock.h
  A engines/lastexpress/menu/trainline.cpp
  A engines/lastexpress/menu/trainline.h
    engines/lastexpress/menu/menu.cpp
    engines/lastexpress/module.mk



diff --git a/engines/lastexpress/menu/clock.cpp b/engines/lastexpress/menu/clock.cpp
new file mode 100644
index 0000000..b0e6a26
--- /dev/null
+++ b/engines/lastexpress/menu/clock.cpp
@@ -0,0 +1,106 @@
+/* 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 "lastexpress/menu/clock.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
+	_frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
+	_frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
+	_frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
+	_frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
+}
+
+Clock::~Clock() {
+	SAFE_DELETE(_frameMinutes);
+	SAFE_DELETE(_frameHour);
+	SAFE_DELETE(_frameSun);
+	SAFE_DELETE(_frameDate);
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+void Clock::clear() {
+	getScenes()->removeFromQueue(_frameMinutes);
+	getScenes()->removeFromQueue(_frameHour);
+	getScenes()->removeFromQueue(_frameSun);
+	getScenes()->removeFromQueue(_frameDate);
+}
+
+void Clock::draw(uint32 time) {
+	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+	// Check that sequences have been loaded
+	if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
+		error("Clock::process: clock sequences have not been loaded correctly!");
+
+	// Clear existing frames
+	clear();
+
+	// Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
+	// Game ends at:   4941000 = 7:30 p.m. on July 26, 1914
+	// Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
+
+	// 15 = 1 second
+	// 15 * 60 = 900 = 1 minute
+	// 900 * 60 = 54000 = 1 hour
+	// 54000 * 24 = 1296000 = 1 day
+
+	// Calculate each sequence index from the current time
+
+	uint8 hour = 0;
+	uint8 minute = 0;
+	State::getHourMinutes(time, &hour, &minute);
+	uint32 index_date = 18 * time / 1296000;
+	if (hour == 23)
+		index_date += 18 * minute / 60;
+
+	// Set sequences frames
+	_frameMinutes->setFrame(minute);
+	_frameHour->setFrame((5 * hour + minute / 12) % 60);
+	_frameSun->setFrame((5 * hour + minute / 12) % 120);
+	_frameDate->setFrame((uint16)index_date);
+
+	// Adjust z-order and queue
+	_frameMinutes->getInfo()->location = 1;
+	_frameHour->getInfo()->location = 1;
+	_frameSun->getInfo()->location = 1;
+	_frameDate->getInfo()->location = 1;
+
+	getScenes()->addToQueue(_frameMinutes);
+	getScenes()->addToQueue(_frameHour);
+	getScenes()->addToQueue(_frameSun);
+	getScenes()->addToQueue(_frameDate);
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/menu/clock.h b/engines/lastexpress/menu/clock.h
new file mode 100644
index 0000000..339a186
--- /dev/null
+++ b/engines/lastexpress/menu/clock.h
@@ -0,0 +1,53 @@
+/* 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 LASTEXPRESS_CLOCK_H
+#define LASTEXPRESS_CLOCK_H
+
+#include "common/scummsys.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SequenceFrame;
+
+class Clock {
+public:
+	explicit Clock(LastExpressEngine *engine);
+	~Clock();
+
+	void draw(uint32 time);
+	void clear();
+
+private:
+	LastExpressEngine *_engine;
+
+	// Frames
+	SequenceFrame *_frameMinutes;
+	SequenceFrame *_frameHour;
+	SequenceFrame *_frameSun;
+	SequenceFrame *_frameDate;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_CLOCK_H
diff --git a/engines/lastexpress/menu/menu.cpp b/engines/lastexpress/menu/menu.cpp
index b7e6a14..e55a6d5 100644
--- a/engines/lastexpress/menu/menu.cpp
+++ b/engines/lastexpress/menu/menu.cpp
@@ -38,6 +38,9 @@
 #include "lastexpress/game/sound.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/menu/clock.h"
+#include "lastexpress/menu/trainline.h"
+
 #include "lastexpress/graphics.h"
 #include "lastexpress/helpers.h"
 #include "lastexpress/lastexpress.h"
@@ -119,45 +122,6 @@ enum StartMenuTooltips {
 //////////////////////////////////////////////////////////////////////////
 // DATA
 //////////////////////////////////////////////////////////////////////////
-
-// Information about the cities on the train line
-static const struct {
-	uint8 frame;
-	TimeValue time;
-} _trainCities[31] = {
-	{0, kTimeCityParis},
-	{9, kTimeCityEpernay},
-	{11, kTimeCityChalons},
-	{16, kTimeCityBarLeDuc},
-	{21, kTimeCityNancy},
-	{25, kTimeCityLuneville},
-	{35, kTimeCityAvricourt},
-	{37, kTimeCityDeutschAvricourt},
-	{40, kTimeCityStrasbourg},
-	{53, kTimeCityBadenOos},
-	{56, kTimeCityKarlsruhe},
-	{60, kTimeCityStuttgart},
-	{63, kTimeCityGeislingen},
-	{66, kTimeCityUlm},
-	{68, kTimeCityAugsburg},
-	{73, kTimeCityMunich},
-	{84, kTimeCitySalzbourg},
-	{89, kTimeCityAttnangPuchheim},
-	{97, kTimeCityWels},
-	{100, kTimeCityLinz},
-	{104, kTimeCityAmstetten},
-	{111, kTimeCityVienna},
-	{120, kTimeCityPoszony},
-	{124, kTimeCityGalanta},
-	{132, kTimeCityBudapest},
-	{148, kTimeCityBelgrade},
-	/* Line 1 ends at 150 - line 2 begins at 0 */
-	{157, kTimeCityNish},
-	{165, kTimeCityTzaribrod},
-	{174, kTimeCitySofia},
-	{198, kTimeCityAdrianople},
-	{210, kTimeCityConstantinople}};
-
 static const struct {
 	TimeValue time;
 	uint index;
@@ -174,185 +138,6 @@ static const struct {
 };
 
 //////////////////////////////////////////////////////////////////////////
-// Clock
-//////////////////////////////////////////////////////////////////////////
-class Clock {
-public:
-	explicit Clock(LastExpressEngine *engine);
-	~Clock();
-
-	void draw(uint32 time);
-	void clear();
-
-private:
-	LastExpressEngine *_engine;
-
-	// Frames
-	SequenceFrame *_frameMinutes;
-	SequenceFrame *_frameHour;
-	SequenceFrame *_frameSun;
-	SequenceFrame *_frameDate;
-};
-
-Clock::Clock(LastExpressEngine *engine) : _engine(engine), _frameMinutes(NULL), _frameHour(NULL), _frameSun(NULL), _frameDate(NULL) {
-	_frameMinutes = new SequenceFrame(loadSequence("eggmin.seq"), 0, true);
-	_frameHour = new SequenceFrame(loadSequence("egghour.seq"), 0, true);
-	_frameSun = new SequenceFrame(loadSequence("sun.seq"), 0, true);
-	_frameDate = new SequenceFrame(loadSequence("datenew.seq"), 0, true);
-}
-
-Clock::~Clock() {
-	SAFE_DELETE(_frameMinutes);
-	SAFE_DELETE(_frameHour);
-	SAFE_DELETE(_frameSun);
-	SAFE_DELETE(_frameDate);
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-void Clock::clear() {
-	getScenes()->removeFromQueue(_frameMinutes);
-	getScenes()->removeFromQueue(_frameHour);
-	getScenes()->removeFromQueue(_frameSun);
-	getScenes()->removeFromQueue(_frameDate);
-}
-
-void Clock::draw(uint32 time) {
-	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
-	// Check that sequences have been loaded
-	if (!_frameMinutes || !_frameHour || !_frameSun || !_frameDate)
-		error("Clock::process: clock sequences have not been loaded correctly!");
-
-	// Clear existing frames
-	clear();
-
-	// Game starts at: 1037700 = 7:13 p.m. on July 24, 1914
-	// Game ends at:   4941000 = 7:30 p.m. on July 26, 1914
-	// Game lasts for: 3903300 = 2 days + 17 mins = 2897 mins
-
-	// 15 = 1 second
-	// 15 * 60 = 900 = 1 minute
-	// 900 * 60 = 54000 = 1 hour
-	// 54000 * 24 = 1296000 = 1 day
-
-	// Calculate each sequence index from the current time
-
-	uint8 hour = 0;
-	uint8 minute = 0;
-	State::getHourMinutes(time, &hour, &minute);
-	uint32 index_date = 18 * time / 1296000;
-	if (hour == 23)
-		index_date += 18 * minute / 60;
-
-	// Set sequences frames
-	_frameMinutes->setFrame(minute);
-	_frameHour->setFrame((5 * hour + minute / 12) % 60);
-	_frameSun->setFrame((5 * hour + minute / 12) % 120);
-	_frameDate->setFrame((uint16)index_date);
-
-	// Adjust z-order and queue
-	_frameMinutes->getInfo()->location = 1;
-	_frameHour->getInfo()->location = 1;
-	_frameSun->getInfo()->location = 1;
-	_frameDate->getInfo()->location = 1;
-
-	getScenes()->addToQueue(_frameMinutes);
-	getScenes()->addToQueue(_frameHour);
-	getScenes()->addToQueue(_frameSun);
-	getScenes()->addToQueue(_frameDate);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// TrainLine
-//////////////////////////////////////////////////////////////////////////
-class TrainLine {
-public:
-	explicit TrainLine(LastExpressEngine *engine);
-	~TrainLine();
-
-	void draw(uint32 time);
-	void clear();
-
-private:
-	LastExpressEngine *_engine;
-
-	// Frames
-	SequenceFrame *_frameLine1;
-	SequenceFrame *_frameLine2;
-};
-
-TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
-	_frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
-	_frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
-}
-
-TrainLine::~TrainLine() {
-	SAFE_DELETE(_frameLine1);
-	SAFE_DELETE(_frameLine2);
-
-	// Zero passed pointers
-	_engine = NULL;
-}
-
-void TrainLine::clear() {
-	getScenes()->removeFromQueue(_frameLine1);
-	getScenes()->removeFromQueue(_frameLine2);
-}
-
-// Draw the train line at the time
-//  line1: 150 frames (=> Belgrade)
-//  line2: 61 frames (=> Constantinople)
-void TrainLine::draw(uint32 time) {
-	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
-
-	// Check that sequences have been loaded
-	if (!_frameLine1 || !_frameLine2)
-		error("TrainLine::process: Line sequences have not been loaded correctly!");
-
-	// Clear existing frames
-	clear();
-
-	// Get the index of the last city the train has visited
-	uint index = 0;
-	for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
-		if ((uint32)_trainCities[i].time <= time)
-			index = i;
-
-	uint16 frame;
-	if (time > (uint32)_trainCities[index].time) {
-		// Interpolate linearly to use a frame between the cities
-		uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
-		uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
-		uint traveledTime = (time - (uint)_trainCities[index].time);
-		frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
-	} else {
-		// Exactly on the city
-		frame = _trainCities[index].frame;
-	}
-
-	// Set frame, z-order and queue
-	if (frame < 150) {
-		_frameLine1->setFrame(frame);
-
-		_frameLine1->getInfo()->location = 1;
-		getScenes()->addToQueue(_frameLine1);
-	} else {
-		// We passed Belgrade
-		_frameLine1->setFrame(149);
-		_frameLine2->setFrame(frame - 150);
-
-		_frameLine1->getInfo()->location = 1;
-		_frameLine2->getInfo()->location = 1;
-
-		getScenes()->addToQueue(_frameLine1);
-		getScenes()->addToQueue(_frameLine2);
-	}
-}
-
-
-//////////////////////////////////////////////////////////////////////////
 // Menu
 //////////////////////////////////////////////////////////////////////////
 Menu::Menu(LastExpressEngine *engine) : _engine(engine),
diff --git a/engines/lastexpress/menu/trainline.cpp b/engines/lastexpress/menu/trainline.cpp
new file mode 100644
index 0000000..df08abf
--- /dev/null
+++ b/engines/lastexpress/menu/trainline.cpp
@@ -0,0 +1,142 @@
+/* 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 "lastexpress/menu/trainline.h"
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/game/scenes.h"
+
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+// Information about the cities on the train line
+static const struct {
+	uint8 frame;
+	TimeValue time;
+} _trainCities[31] = {
+	{0, kTimeCityParis},
+	{9, kTimeCityEpernay},
+	{11, kTimeCityChalons},
+	{16, kTimeCityBarLeDuc},
+	{21, kTimeCityNancy},
+	{25, kTimeCityLuneville},
+	{35, kTimeCityAvricourt},
+	{37, kTimeCityDeutschAvricourt},
+	{40, kTimeCityStrasbourg},
+	{53, kTimeCityBadenOos},
+	{56, kTimeCityKarlsruhe},
+	{60, kTimeCityStuttgart},
+	{63, kTimeCityGeislingen},
+	{66, kTimeCityUlm},
+	{68, kTimeCityAugsburg},
+	{73, kTimeCityMunich},
+	{84, kTimeCitySalzbourg},
+	{89, kTimeCityAttnangPuchheim},
+	{97, kTimeCityWels},
+	{100, kTimeCityLinz},
+	{104, kTimeCityAmstetten},
+	{111, kTimeCityVienna},
+	{120, kTimeCityPoszony},
+	{124, kTimeCityGalanta},
+	{132, kTimeCityBudapest},
+	{148, kTimeCityBelgrade},
+	/* Line 1 ends at 150 - line 2 begins at 0 */
+	{157, kTimeCityNish},
+	{165, kTimeCityTzaribrod},
+	{174, kTimeCitySofia},
+	{198, kTimeCityAdrianople},
+	{210, kTimeCityConstantinople}
+};
+
+TrainLine::TrainLine(LastExpressEngine *engine) : _engine(engine), _frameLine1(NULL), _frameLine2(NULL) {
+	_frameLine1 = new SequenceFrame(loadSequence("line1.seq"), 0, true);
+	_frameLine2 = new SequenceFrame(loadSequence("line2.seq"), 0, true);
+}
+
+TrainLine::~TrainLine() {
+	SAFE_DELETE(_frameLine1);
+	SAFE_DELETE(_frameLine2);
+
+	// Zero passed pointers
+	_engine = NULL;
+}
+
+void TrainLine::clear() {
+	getScenes()->removeFromQueue(_frameLine1);
+	getScenes()->removeFromQueue(_frameLine2);
+}
+
+// Draw the train line at the time
+//  line1: 150 frames (=> Belgrade)
+//  line2: 61 frames (=> Constantinople)
+void TrainLine::draw(uint32 time) {
+	assert(time >= kTimeCityParis && time <= kTimeCityConstantinople);
+
+	// Check that sequences have been loaded
+	if (!_frameLine1 || !_frameLine2)
+		error("TrainLine::process: Line sequences have not been loaded correctly!");
+
+	// Clear existing frames
+	clear();
+
+	// Get the index of the last city the train has visited
+	uint index = 0;
+	for (uint i = 0; i < ARRAYSIZE(_trainCities); i++)
+		if ((uint32)_trainCities[i].time <= time)
+			index = i;
+
+	uint16 frame;
+	if (time > (uint32)_trainCities[index].time) {
+		// Interpolate linearly to use a frame between the cities
+		uint8 diffFrames = _trainCities[index + 1].frame - _trainCities[index].frame;
+		uint diffTimeCities = (uint)(_trainCities[index + 1].time - _trainCities[index].time);
+		uint traveledTime = (time - (uint)_trainCities[index].time);
+		frame = (uint16)(_trainCities[index].frame + (traveledTime * diffFrames) / diffTimeCities);
+	} else {
+		// Exactly on the city
+		frame = _trainCities[index].frame;
+	}
+
+	// Set frame, z-order and queue
+	if (frame < 150) {
+		_frameLine1->setFrame(frame);
+
+		_frameLine1->getInfo()->location = 1;
+		getScenes()->addToQueue(_frameLine1);
+	} else {
+		// We passed Belgrade
+		_frameLine1->setFrame(149);
+		_frameLine2->setFrame(frame - 150);
+
+		_frameLine1->getInfo()->location = 1;
+		_frameLine2->getInfo()->location = 1;
+
+		getScenes()->addToQueue(_frameLine1);
+		getScenes()->addToQueue(_frameLine2);
+	}
+}
+
+} // End of namespace LastExpress
diff --git a/engines/lastexpress/menu/trainline.h b/engines/lastexpress/menu/trainline.h
new file mode 100644
index 0000000..af6a121
--- /dev/null
+++ b/engines/lastexpress/menu/trainline.h
@@ -0,0 +1,51 @@
+/* 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 LASTEXPRESS_TRAINLINE_H
+#define LASTEXPRESS_TRAINLINE_H
+
+#include "common/scummsys.h"
+
+namespace LastExpress {
+
+class LastExpressEngine;
+class SequenceFrame;
+
+class TrainLine {
+public:
+	explicit TrainLine(LastExpressEngine *engine);
+	~TrainLine();
+
+	void draw(uint32 time);
+	void clear();
+
+private:
+	LastExpressEngine *_engine;
+
+	// Frames
+	SequenceFrame *_frameLine1;
+	SequenceFrame *_frameLine2;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_TRAINLINE_H
diff --git a/engines/lastexpress/module.mk b/engines/lastexpress/module.mk
index e38772a..71d81da 100644
--- a/engines/lastexpress/module.mk
+++ b/engines/lastexpress/module.mk
@@ -63,7 +63,9 @@ MODULE_OBJS := \
 	game/scenes.o \
 	game/sound.o \
 	game/state.o \
+	menu/clock.o \
 	menu/menu.o \
+	menu/trainline.o \
 	debug.o \
 	detection.o \
 	graphics.o \


Commit: b694a78f62a02253bca2a5611314599ae7fce725
    https://github.com/scummvm/scummvm/commit/b694a78f62a02253bca2a5611314599ae7fce725
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-23T05:52:52-07:00

Commit Message:
ANALYSIS: Add static casts to is* functions

This fixes a potential problem with passing char values that would be sign-extended and yield unexpected results.
See http://msdn.microsoft.com/en-us/library/ms245348.aspx

Changed paths:
    base/commandLine.cpp
    common/config-file.cpp
    common/config-manager.cpp
    common/str.cpp
    common/xmlparser.cpp
    common/xmlparser.h
    engines/agi/wagparser.cpp
    engines/agos/script_pn.cpp
    engines/cine/detection.cpp
    engines/drascula/interface.cpp
    engines/hugo/parser.cpp
    engines/hugo/util.cpp
    engines/kyra/gui.cpp
    engines/m4/dialogs.cpp
    engines/parallaction/parser_br.cpp
    engines/parallaction/parser_ns.cpp
    engines/queen/talk.cpp
    engines/sci/engine/kstring.cpp
    engines/sci/graphics/text16.cpp
    engines/sci/resource.cpp
    engines/sci/resource_audio.cpp
    engines/scumm/smush/smush_player.cpp
    engines/scumm/string.cpp
    engines/sky/detection.cpp
    engines/sword1/animation.cpp
    engines/sword25/util/lua/llex.cpp
    engines/touche/menu.cpp
    graphics/font.cpp



diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 6cb8585..2620d69 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -279,7 +279,7 @@ void registerDefaults() {
 // resp. between "--some-option" and "--no-some-option".
 #define DO_OPTION_BOOL(shortCmd, longCmd) \
 	if (isLongCmd ? (!strcmp(s+2, longCmd) || !strcmp(s+2, "no-"longCmd)) : (tolower(s[1]) == shortCmd)) { \
-		bool boolValue = (islower(s[1]) != 0); \
+		bool boolValue = (islower(static_cast<unsigned char>(s[1])) != 0); \
 		s += 2; \
 		if (isLongCmd) { \
 			boolValue = !strcmp(s, longCmd); \
diff --git a/common/config-file.cpp b/common/config-file.cpp
index 5594113..ea3feff 100644
--- a/common/config-file.cpp
+++ b/common/config-file.cpp
@@ -38,7 +38,7 @@ namespace Common {
  */
 bool ConfigFile::isValidName(const Common::String &name) {
 	const char *p = name.c_str();
-	while (*p && (isalnum(*p) || *p == '-' || *p == '_' || *p == '.'))
+	while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
 		p++;
 	return *p == 0;
 }
@@ -116,7 +116,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
 			// is, verify that it only consists of alphanumerics,
 			// periods, dashes and underscores). Mohawk Living Books games
 			// can have periods in their section names.
-			while (*p && (isalnum(*p) || *p == '-' || *p == '_' || *p == '.'))
+			while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_' || *p == '.'))
 				p++;
 
 			if (*p == '\0')
@@ -139,7 +139,7 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) {
 
 			// Skip leading whitespaces
 			const char *t = line.c_str();
-			while (isspace(*t))
+			while (isspace(static_cast<unsigned char>(*t)))
 				t++;
 
 			// Skip empty lines / lines with only whitespace
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
index 3941e27..a9d8c89 100644
--- a/common/config-manager.cpp
+++ b/common/config-manager.cpp
@@ -31,7 +31,7 @@ DECLARE_SINGLETON(Common::ConfigManager);
 
 static bool isValidDomainName(const Common::String &domName) {
 	const char *p = domName.c_str();
-	while (*p && (isalnum(*p) || *p == '-' || *p == '_'))
+	while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
 		p++;
 	return *p == 0;
 }
@@ -187,7 +187,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
 			// Get the domain name, and check whether it's valid (that
 			// is, verify that it only consists of alphanumerics,
 			// dashes and underscores).
-			while (*p && (isalnum(*p) || *p == '-' || *p == '_'))
+			while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
 				p++;
 
 			if (*p == '\0')
@@ -205,7 +205,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) {
 
 			// Skip leading whitespaces
 			const char *t = line.c_str();
-			while (isspace(*t))
+			while (isspace(static_cast<unsigned char>(*t)))
 				t++;
 
 			// Skip empty lines / lines with only whitespace
diff --git a/common/str.cpp b/common/str.cpp
index a2cd4a01..32f4b44 100644
--- a/common/str.cpp
+++ b/common/str.cpp
@@ -405,7 +405,7 @@ void String::trim() {
 	makeUnique();
 
 	// Trim trailing whitespace
-	while (_size >= 1 && isspace(_str[_size - 1]))
+	while (_size >= 1 && isspace(static_cast<unsigned char>(_str[_size - 1])))
 		--_size;
 	_str[_size] = 0;
 
@@ -606,14 +606,14 @@ String operator+(const String &x, char y) {
 }
 
 char *ltrim(char *t) {
-	while (isspace(*t))
+	while (isspace(static_cast<unsigned char>(*t)))
 		t++;
 	return t;
 }
 
 char *rtrim(char *t) {
 	int l = strlen(t) - 1;
-	while (l >= 0 && isspace(t[l]))
+	while (l >= 0 && isspace(static_cast<unsigned char>(t[l])))
 		t[l--] = 0;
 	return t;
 }
diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp
index 5217c4e..6236199 100644
--- a/common/xmlparser.cpp
+++ b/common/xmlparser.cpp
@@ -263,7 +263,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
 	int *num_ptr;
 
 	while (count--) {
-		while (isspace(*key))
+		while (isspace(static_cast<unsigned char>(*key)))
 			key++;
 
 		num_ptr = va_arg(args, int*);
@@ -271,7 +271,7 @@ bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) {
 
 		key = parseEnd;
 
-		while (isspace(*key))
+		while (isspace(static_cast<unsigned char>(*key)))
 			key++;
 
 		if (count && *key++ != ',')
@@ -463,10 +463,10 @@ bool XMLParser::parse() {
 }
 
 bool XMLParser::skipSpaces() {
-	if (!isspace(_char))
+	if (!isspace(static_cast<unsigned char>(_char)))
 		return false;
 
-	while (_char && isspace(_char))
+	while (_char && isspace(static_cast<unsigned char>(_char)))
 		_char = _stream->readByte();
 
 	return true;
@@ -516,7 +516,7 @@ bool XMLParser::parseToken() {
 		_char = _stream->readByte();
 	}
 
-	return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
+	return isspace(static_cast<unsigned char>(_char)) != 0 || _char == '>' || _char == '=' || _char == '/';
 }
 
 } // End of namespace Common
diff --git a/common/xmlparser.h b/common/xmlparser.h
index 7923e43..40c779b 100644
--- a/common/xmlparser.h
+++ b/common/xmlparser.h
@@ -294,7 +294,7 @@ protected:
 	 * in their name.
 	 */
 	virtual inline bool isValidNameChar(char c) {
-		return isalnum(c) || c == '_';
+		return isalnum(static_cast<unsigned char>(c)) || c == '_';
 	}
 
 	/**
diff --git a/engines/agi/wagparser.cpp b/engines/agi/wagparser.cpp
index 14159c0..39f9e0d 100644
--- a/engines/agi/wagparser.cpp
+++ b/engines/agi/wagparser.cpp
@@ -112,11 +112,11 @@ WagFileParser::~WagFileParser() {
 bool WagFileParser::checkAgiVersionProperty(const WagProperty &version) const {
 	if (version.getCode() == WagProperty::PC_INTVERSION && // Must be AGI interpreter version property
 		version.getSize() >= 3 && // Need at least three characters for a version number like "X.Y"
-		isdigit(version.getData()[0]) && // And the first character must be a digit
+		isdigit(static_cast<unsigned char>(version.getData()[0])) && // And the first character must be a digit
 		(version.getData()[1] == ',' || version.getData()[1] == '.')) { // And the second a comma or a period
 
 		for (int i = 2; i < version.getSize(); i++) // And the rest must all be digits
-			if (!isdigit(version.getData()[i]))
+			if (!isdigit(static_cast<unsigned char>(version.getData()[i])))
 				return false; // Bail out if found a non-digit after the decimal point
 
 		return true;
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index bde59b7..3bd8ce1 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -465,8 +465,8 @@ void AGOSEngine_PN::opn_opcode35() {
 void AGOSEngine_PN::opn_opcode36() {
 	for (int i = 0; i < _dataBase[57] + 1; ++i)
 		_wordcp[i] = 0;
-	if (isspace(*_inpp))
-		while ((*_inpp) && (isspace(*_inpp)))
+	if (isspace(static_cast<unsigned char>(*_inpp)))
+		while ((*_inpp) && (isspace(static_cast<unsigned char>(*_inpp))))
 			_inpp++;
 	if (*_inpp == 0) {
 		setScriptReturn(false);
@@ -480,7 +480,7 @@ void AGOSEngine_PN::opn_opcode36() {
 	}
 
 	int ct = 1;
-	while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(*_inpp)) && (*_inpp != '\0') &&
+	while ((*_inpp != '.') && (*_inpp != ',') && (!isspace(static_cast<unsigned char>(*_inpp))) && (*_inpp != '\0') &&
 		(*_inpp!='"')) {
 		if (ct < _dataBase[57])
 			_wordcp[ct++] = *_inpp;
@@ -580,7 +580,7 @@ void AGOSEngine_PN::opn_opcode46() {
 		return;
 	}
 	x++;
-	while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(*x)) && (*x != '\0'))
+	while ((*x != '.') && (*x != ',') && (*x != '"') && (!isspace(static_cast<unsigned char>(*x))) && (*x != '\0'))
 		pcf(*x++);
 	setScriptReturn(true);
 }
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index cffeb29..ba02515 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -141,7 +141,7 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
 
 		for (file = filenames.begin(); file != filenames.end(); ++file) {
 			// Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not).
-			if (!isdigit(file->lastChar()))
+			if (!isdigit(static_cast<unsigned char>(file->lastChar())))
 				continue;
 
 			// Obtain the last digit of the filename, since they correspond to the save slot
diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp
index eb36bae..e3a9708 100644
--- a/engines/drascula/interface.cpp
+++ b/engines/drascula/interface.cpp
@@ -159,7 +159,7 @@ void DrasculaEngine::enterName() {
 		key = getScan();
 
 		if (key != 0) {
-			if (key >= 0 && key <= 0xFF && isalpha(key))
+			if (key >= 0 && key <= 0xFF && isalpha(static_cast<unsigned char>(key)))
 				select2[v] = tolower(key);
 			else if ((key >= Common::KEYCODE_0 && key <= Common::KEYCODE_9) || key == Common::KEYCODE_SPACE)
 				select2[v] = key;
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 5cb97f2..38a8e4e 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -235,7 +235,7 @@ void Parser::charHandler() {
 			if (_cmdLineIndex >= kMaxLineSize) {
 				//MessageBeep(MB_ICONASTERISK);
 				warning("STUB: MessageBeep() - Command line too long");
-			} else if (isprint(c)) {
+			} else if (isprint(static_cast<unsigned char>(c))) {
 				_cmdLine[_cmdLineIndex++] = c;
 				_cmdLine[_cmdLineIndex] = '\0';
 			}
diff --git a/engines/hugo/util.cpp b/engines/hugo/util.cpp
index a936a23..6dc9890 100644
--- a/engines/hugo/util.cpp
+++ b/engines/hugo/util.cpp
@@ -119,7 +119,7 @@ char *strlwr(char *buffer) {
 	char *result = buffer;
 
 	while (*buffer != '\0') {
-		if (isupper(*buffer))
+		if (isupper(static_cast<unsigned char>(*buffer)))
 			*buffer = tolower(*buffer);
 		buffer++;
 	}
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index f58ca01..29cbe20 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -375,7 +375,7 @@ void GUI::updateSaveList(bool excludeQuickSaves) {
 		s1 = (*i)[i->size()-3];
 		s2 = (*i)[i->size()-2];
 		s3 = (*i)[i->size()-1];
-		if (!isdigit(s1) || !isdigit(s2) || !isdigit(s3))
+		if (!isdigit(static_cast<unsigned char>(s1)) || !isdigit(static_cast<unsigned char>(s2)) || !isdigit(static_cast<unsigned char>(s3)))
 			continue;
 		s1 -= '0';
 		s2 -= '0';
diff --git a/engines/m4/dialogs.cpp b/engines/m4/dialogs.cpp
index 390ca71..2b2c479 100644
--- a/engines/m4/dialogs.cpp
+++ b/engines/m4/dialogs.cpp
@@ -265,7 +265,7 @@ void Dialog::setupInputArea() {
  */
 bool Dialog::matchCommand(const char *s1, const char *s2) {
 	bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0;
-	_commandCase = isupper(*s1);
+	_commandCase = isupper(static_cast<unsigned char>(*s1));
 	return result;
 }
 
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index f53d71c..df53ecc 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -524,14 +524,14 @@ DECLARE_COMMAND_PARSER(location)  {
 	ctxt.cmd->_startPos.x = -1000;
 	ctxt.cmd->_startPos2.x = -1000;
 	if (_tokens[ctxt.nextToken][0] != '\0') {
-		if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
+		if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
 			ctxt.cmd->_startPos.x = atoi(_tokens[ctxt.nextToken]);
 			ctxt.nextToken++;
 			ctxt.cmd->_startPos.y = atoi(_tokens[ctxt.nextToken]);
 			ctxt.nextToken++;
 		}
 
-		if (isdigit(_tokens[ctxt.nextToken][0]) || _tokens[ctxt.nextToken][0] == '-') {
+		if (isdigit(static_cast<unsigned char>(_tokens[ctxt.nextToken][0])) || _tokens[ctxt.nextToken][0] == '-') {
 			ctxt.cmd->_startPos2.x = atoi(_tokens[ctxt.nextToken]);
 			ctxt.nextToken++;
 			ctxt.cmd->_startPos2.y = atoi(_tokens[ctxt.nextToken]);
@@ -677,7 +677,7 @@ DECLARE_COMMAND_PARSER(text)  {
 
 	createCommand(_parser->_lookup);
 
-	if (isdigit(_tokens[1][1])) {
+	if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
 		ctxt.cmd->_zeta0 = atoi(_tokens[1]);
 		ctxt.nextToken++;
 	} else {
@@ -714,7 +714,7 @@ DECLARE_COMMAND_PARSER(unary)  {
 DECLARE_ZONE_PARSER(limits)  {
 	debugC(7, kDebugParser, "ZONE_PARSER(limits) ");
 
-	if (isalpha(_tokens[1][1])) {
+	if (isalpha(static_cast<unsigned char>(_tokens[1][1]))) {
 		ctxt.z->_flags |= kFlagsAnimLinked;
 		ctxt.z->_linkedName = _tokens[1];
 	} else {
@@ -1003,7 +1003,7 @@ DECLARE_INSTRUCTION_PARSER(text)  {
 
 	int _si = 1;
 
-	if (isdigit(_tokens[1][1])) {
+	if (isdigit(static_cast<unsigned char>(_tokens[1][1]))) {
 		ctxt.inst->_y = atoi(_tokens[1]);
 		_si = 2;
 	} else {
@@ -1066,7 +1066,7 @@ DECLARE_INSTRUCTION_PARSER(endif)  {
 
 void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) {
 
-	if (isdigit(str[0]) || str[0] == '-') {
+	if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
 		v.setImmediate(atoi(str));
 		return;
 	}
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 213f0ae..100b608 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -534,7 +534,7 @@ DECLARE_INSTRUCTION_PARSER(endscript)  {
 
 void ProgramParser_ns::parseRValue(ScriptVar &v, const char *str) {
 
-	if (isdigit(str[0]) || str[0] == '-') {
+	if (isdigit(static_cast<unsigned char>(str[0])) || str[0] == '-') {
 		v.setImmediate(atoi(str));
 		return;
 	}
diff --git a/engines/queen/talk.cpp b/engines/queen/talk.cpp
index b83bf60..1f8d9b2 100644
--- a/engines/queen/talk.cpp
+++ b/engines/queen/talk.cpp
@@ -658,7 +658,7 @@ void Talk::stringAnimation(const SpeechParameters *parameters, int startFrame, i
 	} else if (parameters->animation[0] == 'E') {
 		// Talking head animation
 		return;
-	} else if (!isdigit(parameters->animation[0])) {
+	} else if (!isdigit(static_cast<unsigned char>(parameters->animation[0]))) {
 		debug(6, "Error in speak string animation: '%s'", parameters->animation);
 		return;
 	} else
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index 07b87a7..9f10691 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -238,14 +238,14 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
 
 			/* int writelength; -- unused atm */
 
-			if (xfer && (isdigit(xfer) || xfer == '-' || xfer == '=')) {
+			if (xfer && (isdigit(static_cast<unsigned char>(xfer)) || xfer == '-' || xfer == '=')) {
 				char *destp;
 
 				if (xfer == '0')
 					fillchar = '0';
 				else if (xfer == '=')
 					align = ALIGN_CENTER;
-				else if (isdigit(xfer) || (xfer == '-'))
+				else if (isdigit(static_cast<unsigned char>(xfer)) || (xfer == '-'))
 					source--; // Go to start of length argument
 
 				str_leng = strtol(source, &destp, 10);
diff --git a/engines/sci/graphics/text16.cpp b/engines/sci/graphics/text16.cpp
index c2f71a0..84547d9 100644
--- a/engines/sci/graphics/text16.cpp
+++ b/engines/sci/graphics/text16.cpp
@@ -100,7 +100,7 @@ int16 GfxText16::CodeProcessing(const char *&text, GuiResourceId orgFontId, int1
 	//  cX -> sets textColor to _textColors[X-1]
 	curCode = textCode[0];
 	curCodeParm = textCode[1];
-	if (isdigit(curCodeParm)) {
+	if (isdigit(static_cast<unsigned char>(curCodeParm))) {
 		curCodeParm -= '0';
 	} else {
 		curCodeParm = -1;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index fa70481..f18b6c9 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -1555,7 +1555,7 @@ void ResourceManager::readResourcePatches() {
 			name = (*x)->getName();
 
 			// SCI1 scheme
-			if (isdigit(name[0])) {
+			if (isdigit(static_cast<unsigned char>(name[0]))) {
 				char *end = 0;
 				resourceNr = strtol(name.c_str(), &end, 10);
 				bAdd = (*end == '.'); // Ensure the next character is the period
@@ -1563,7 +1563,7 @@ void ResourceManager::readResourcePatches() {
 				// SCI0 scheme
 				int resname_len = strlen(szResType);
 				if (scumm_strnicmp(name.c_str(), szResType, resname_len) == 0
-					&& !isalpha(name[resname_len + 1])) {
+					&& !isalpha(static_cast<unsigned char>(name[resname_len + 1]))) {
 					resourceNr = atoi(name.c_str() + resname_len + 1);
 					bAdd = true;
 				}
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index 032040f..f3a3c8d 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -197,7 +197,7 @@ void ResourceManager::readWaveAudioPatches() {
 	for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) {
 		Common::String name = (*x)->getName();
 
-		if (isdigit(name[0]))
+		if (isdigit(static_cast<unsigned char>(name[0])))
 			processWavePatch(ResourceId(kResourceTypeAudio, atoi(name.c_str())), name);
 	}
 }
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 6650257..2f4e86b 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -90,13 +90,13 @@ public:
 			assert(def_end != NULL);
 
 			char *id_end = def_end;
-			while (id_end >= def_start && !isdigit(*(id_end-1))) {
+			while (id_end >= def_start && !isdigit(static_cast<unsigned char>(*(id_end-1)))) {
 				id_end--;
 			}
 
 			assert(id_end > def_start);
 			char *id_start = id_end;
-			while (isdigit(*(id_start - 1))) {
+			while (isdigit(static_cast<unsigned char>(*(id_start - 1)))) {
 				id_start--;
 			}
 
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index 4b3207c..2d2209c 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -1383,10 +1383,10 @@ void ScummEngine_v7::loadLanguageBundle() {
 			} else if (*ptr == '#') {
 				// Number of subtags following a given basetag. We don't need that
 				// information so we just skip it
-			} else if (isdigit(*ptr)) {
+			} else if (isdigit(static_cast<unsigned char>(*ptr))) {
 				int idx = 0;
 				// A number (up to three digits)...
-				while (isdigit(*ptr)) {
+				while (isdigit(static_cast<unsigned char>(*ptr))) {
 					idx = idx * 10 + (*ptr - '0');
 					ptr++;
 				}
@@ -1424,12 +1424,12 @@ void ScummEngine_v7::loadLanguageBundle() {
 		for (i = 0; i < _languageIndexSize; i++) {
 			// First 8 chars in the line give the string ID / 'tag'
 			int j;
-			for (j = 0; j < 8 && !isspace(*ptr); j++, ptr++)
+			for (j = 0; j < 8 && !isspace(static_cast<unsigned char>(*ptr)); j++, ptr++)
 				_languageIndex[i].tag[j] = toupper(*ptr);
 			_languageIndex[i].tag[j] = 0;
 
 			// After that follows a single space which we skip
-			assert(isspace(*ptr));
+			assert(isspace(static_cast<unsigned char>(*ptr)));
 			ptr++;
 
 			// Then comes the translated string: we record an offset to that.
diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp
index f3cce06..a106749 100644
--- a/engines/sky/detection.cpp
+++ b/engines/sky/detection.cpp
@@ -206,7 +206,7 @@ SaveStateList SkyMetaEngine::listSaves(const char *target) const {
 		// Extract the extension
 		Common::String ext = file->c_str() + file->size() - 3;
 		ext.toUppercase();
-		if (isdigit(ext[0]) && isdigit(ext[1]) && isdigit(ext[2])){
+		if (isdigit(static_cast<unsigned char>(ext[0])) && isdigit(static_cast<unsigned char>(ext[1])) && isdigit(static_cast<unsigned char>(ext[2]))){
 			int slotNum = atoi(ext.c_str());
 			Common::InSaveFile *in = saveFileMan->openForLoading(*file);
 			if (in) {
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 4ce3e2e..f19efd2 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -114,7 +114,7 @@ bool MoviePlayer::load(uint32 id) {
 				int startFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
 				int endFrame = strtoul(ptr, const_cast<char **>(&ptr), 10);
 
-				while (*ptr && isspace(*ptr))
+				while (*ptr && isspace(static_cast<unsigned char>(*ptr)))
 					ptr++;
 
 				if (startFrame > endFrame) {
diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp
index 4d73a6a..b456ee2 100644
--- a/engines/sword25/util/lua/llex.cpp
+++ b/engines/sword25/util/lua/llex.cpp
@@ -188,7 +188,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
   sprintf(buf, "%.1f", 1.0);
   ls->decpoint = '.';
   for (i = 0; buf[i]; i++) {
-    if (!isspace(buf[i]) && !isdigit(buf[i])) {
+    if (!isspace(static_cast<unsigned char>(buf[i])) && !isdigit(static_cast<unsigned char>(buf[i]))) {
       ls->decpoint = buf[i];
       break;
     }
diff --git a/engines/touche/menu.cpp b/engines/touche/menu.cpp
index f469a95..c58e2f1 100644
--- a/engines/touche/menu.cpp
+++ b/engines/touche/menu.cpp
@@ -103,7 +103,7 @@ struct MenuData {
 	void addCharToDescription(int slot, char chr) {
 		char *description = saveLoadDescriptionsTable[slot];
 		int descriptionLen = strlen(description);
-		if (descriptionLen < 32 && isprint(chr)) {
+		if (descriptionLen < 32 && isprint(static_cast<unsigned char>(chr))) {
 			description[descriptionLen] = chr;
 			description[descriptionLen + 1] = 0;
 		}
diff --git a/graphics/font.cpp b/graphics/font.cpp
index d254c64..0c180ee 100644
--- a/graphics/font.cpp
+++ b/graphics/font.cpp
@@ -948,7 +948,7 @@ int Font::wordWrapText(const Common::String &str, int maxWidth, Common::Array<Co
 			if (lineWidth > 0) {
 				wrapper.add(line, lineWidth);
 				// Trim left side
-				while (tmpStr.size() && isspace(tmpStr[0])) {
+				while (tmpStr.size() && isspace(static_cast<unsigned char>(tmpStr[0]))) {
 					tmpWidth -= getCharWidth(tmpStr[0]);
 					tmpStr.deleteChar(0);
 				}


Commit: 712af61f76148095cd3b8762eeb2b2b10502df1f
    https://github.com/scummvm/scummvm/commit/712af61f76148095cd3b8762eeb2b2b10502df1f
Author: Littleboy (littleboy at users.sourceforge.net)
Date: 2011-06-23T05:52:54-07:00

Commit Message:
BACKENDS: Silence warnings when compiling Win32TaskbarManager with mingw and add CLSID_ShellLink definition

Changed paths:
    backends/taskbar/win32/mingw-compat.h



diff --git a/backends/taskbar/win32/mingw-compat.h b/backends/taskbar/win32/mingw-compat.h
index bf03db9..30ce818 100644
--- a/backends/taskbar/win32/mingw-compat.h
+++ b/backends/taskbar/win32/mingw-compat.h
@@ -45,10 +45,10 @@
 #include <shlguid.h>
 #define CMIC_MASK_ASYNCOK SEE_MASK_ASYNCOK
 
-// Misc enumeration values
-#ifndef SHARD_LINK
+extern const GUID CLSID_ShellLink;
+
+// Shard enumeration value
 #define SHARD_LINK 0x00000006
-#endif
 
 // Taskbar GUID definitions
 DEFINE_GUID(CLSID_TaskbarList,0x56fdf344,0xfd6d,0x11d0,0x95,0x8a,0x0,0x60,0x97,0xc9,0xa0,0x90);
@@ -73,6 +73,9 @@ DECLARE_INTERFACE_(IPropertyStore, IUnknown) {
 	STDMETHOD (GetValue) (REFPROPERTYKEY key, PROPVARIANT *pv) PURE;
 	STDMETHOD (SetValue) (REFPROPERTYKEY key, REFPROPVARIANT propvar) PURE;
 	STDMETHOD (Commit) (void) PURE;
+	
+private:
+	~IPropertyStore();
 };
 typedef IPropertyStore *LPIPropertyStore;
 
@@ -137,6 +140,9 @@ DECLARE_INTERFACE_(ITaskbarList3, IUnknown) {
 	STDMETHOD (SetOverlayIcon) (THIS_ HWND hwnd, HICON hIcon, LPCWSTR pszDescription) PURE;
 	STDMETHOD (SetThumbnailTooltip) (THIS_ HWND hwnd, LPCWSTR pszTip) PURE;
 	STDMETHOD (SetThumbnailClip) (THIS_ HWND hwnd, RECT *prcClip) PURE;
+	
+private:
+	~ITaskbarList3();
 };
 
 typedef ITaskbarList3 *LPITaskbarList3;






More information about the Scummvm-git-logs mailing list