2011-12-31 22:53:24 +11:00
|
|
|
/* 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.
|
2014-02-18 02:34:22 +01:00
|
|
|
*
|
2011-12-31 22:53:24 +11:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2014-02-18 02:34:22 +01:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2011-12-31 22:53:24 +11:00
|
|
|
* GNU General Public License for more details.
|
2014-02-18 02:34:22 +01:00
|
|
|
*
|
2011-12-31 22:53:24 +11:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-03-29 16:39:18 +02:00
|
|
|
/*
|
|
|
|
* This code is based on original Mortville Manor DOS source code
|
|
|
|
* Copyright (c) 1987-1989 Lankhor
|
|
|
|
*/
|
|
|
|
|
2011-12-31 22:53:24 +11:00
|
|
|
#include "mortevielle/mortevielle.h"
|
2013-07-19 11:51:10 +02:00
|
|
|
|
2012-02-13 20:51:36 +11:00
|
|
|
#include "mortevielle/dialogs.h"
|
2012-02-12 12:34:51 +11:00
|
|
|
#include "mortevielle/menu.h"
|
2012-01-17 23:52:36 +11:00
|
|
|
#include "mortevielle/mouse.h"
|
2012-02-26 02:04:25 +01:00
|
|
|
#include "mortevielle/outtext.h"
|
2012-02-12 12:34:51 +11:00
|
|
|
#include "mortevielle/saveload.h"
|
2012-03-10 09:46:51 +01:00
|
|
|
#include "mortevielle/outtext.h"
|
2011-12-31 22:53:24 +11:00
|
|
|
|
2013-07-19 11:51:10 +02:00
|
|
|
#include "common/system.h"
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
#include "common/debug-channels.h"
|
2016-12-05 15:29:23 +01:00
|
|
|
#include "common/translation.h"
|
2013-07-19 11:51:10 +02:00
|
|
|
#include "engines/util.h"
|
|
|
|
#include "engines/engine.h"
|
|
|
|
#include "graphics/palette.h"
|
|
|
|
#include "graphics/pixelformat.h"
|
|
|
|
|
2011-12-31 22:53:24 +11:00
|
|
|
namespace Mortevielle {
|
|
|
|
|
2012-01-05 07:56:45 +11:00
|
|
|
MortevielleEngine *g_vm;
|
|
|
|
|
2013-08-13 08:34:36 +02:00
|
|
|
MortevielleEngine::MortevielleEngine(OSystem *system, const MortevielleGameDescription *gameDesc):
|
2014-01-09 08:32:21 +01:00
|
|
|
Engine(system), _gameDescription(gameDesc), _randomSource("mortevielle") {
|
2016-07-28 11:41:49 +03:00
|
|
|
// Set debug channels
|
|
|
|
DebugMan.addDebugChannel(kMortevielleCore, "core", "Core debugging");
|
|
|
|
DebugMan.addDebugChannel(kMortevielleGraphics, "graphics", "Graphics debugging");
|
|
|
|
|
2012-01-05 07:56:45 +11:00
|
|
|
g_vm = this;
|
2014-01-10 01:46:38 +01:00
|
|
|
_debugger = new Debugger(this);
|
|
|
|
_dialogManager = new DialogManager(this);
|
|
|
|
_screenSurface = new ScreenSurface(this);
|
2014-01-09 08:21:52 +01:00
|
|
|
_mouse = new MouseHandler(this);
|
2014-01-09 08:32:21 +01:00
|
|
|
_text = new TextHandler(this);
|
|
|
|
_soundManager = new SoundManager(this, _mixer);
|
2014-01-10 01:46:38 +01:00
|
|
|
_savegameManager = new SavegameManager(this);
|
2014-01-09 08:21:52 +01:00
|
|
|
_menu = new Menu(this);
|
2013-06-25 20:40:06 +02:00
|
|
|
|
2012-01-17 23:52:36 +11:00
|
|
|
_lastGameFrame = 0;
|
2012-01-21 20:06:08 +11:00
|
|
|
_mouseClick = false;
|
2012-02-12 12:34:51 +11:00
|
|
|
_inMainGameLoop = false;
|
2012-02-12 14:22:56 +11:00
|
|
|
_quitGame = false;
|
2013-09-01 22:04:20 +01:00
|
|
|
_pauseStartTime = -1;
|
2012-03-09 22:25:28 +01:00
|
|
|
|
|
|
|
_roomPresenceLuc = false;
|
|
|
|
_roomPresenceIda = false;
|
|
|
|
_purpleRoomPresenceLeo = false;
|
|
|
|
_roomPresenceGuy = false;
|
|
|
|
_roomPresenceEva = false;
|
|
|
|
_roomPresenceMax = false;
|
|
|
|
_roomPresenceBob = false;
|
|
|
|
_roomPresencePat = false;
|
|
|
|
_toiletsPresenceBobMax = false;
|
|
|
|
_bathRoomPresenceBobMax = false;
|
2013-08-03 14:55:19 +02:00
|
|
|
_juliaRoomPresenceLeo = false;
|
2012-03-27 22:54:50 +02:00
|
|
|
|
2012-03-09 22:25:28 +01:00
|
|
|
_soundOff = false;
|
|
|
|
_largestClearScreen = false;
|
|
|
|
_hiddenHero = false;
|
|
|
|
_heroSearching = false;
|
|
|
|
_keyPressedEsc = false;
|
|
|
|
_reloadCFIEC = false;
|
|
|
|
|
2014-01-17 21:28:08 +01:00
|
|
|
_outsideOnlyFl = true;
|
2012-03-09 22:25:28 +01:00
|
|
|
_col = false;
|
|
|
|
_syn = false;
|
|
|
|
_obpart = false;
|
2012-10-12 07:31:30 +02:00
|
|
|
_destinationOk = false;
|
2012-03-09 22:25:28 +01:00
|
|
|
_anyone = false;
|
2012-10-12 07:31:30 +02:00
|
|
|
_uptodatePresence = false;
|
2012-03-10 08:21:09 +01:00
|
|
|
|
|
|
|
_textColor = 0;
|
2012-03-13 00:06:15 +01:00
|
|
|
_place = -1;
|
2012-03-10 08:21:09 +01:00
|
|
|
|
2012-10-10 08:19:54 +02:00
|
|
|
_x26KeyCount = -1;
|
2012-06-14 18:47:03 +02:00
|
|
|
_caff = -1;
|
2012-06-15 20:39:03 +02:00
|
|
|
_day = 0;
|
2012-06-15 00:27:59 +02:00
|
|
|
|
2013-07-24 18:22:35 +02:00
|
|
|
_curPict = nullptr;
|
2013-07-25 10:32:21 +02:00
|
|
|
_curAnim = nullptr;
|
2013-07-25 10:24:25 +02:00
|
|
|
_rightFramePict = nullptr;
|
2014-01-15 17:56:48 +01:00
|
|
|
|
|
|
|
resetCoreVar();
|
|
|
|
|
|
|
|
_maff = 0;
|
|
|
|
_crep = 0;
|
2014-01-24 22:44:40 +01:00
|
|
|
|
|
|
|
_minute = 0;
|
|
|
|
_curSearchObjId = 0;
|
|
|
|
_controlMenu = 0;
|
|
|
|
_startTime = 0;
|
|
|
|
_endTime = 0;
|
|
|
|
_roomDoorId = OWN_ROOM;
|
|
|
|
_openObjCount = 0;
|
|
|
|
_takeObjCount = 0;
|
|
|
|
_num = 0;
|
|
|
|
_searchCount = 0;
|
|
|
|
_introSpeechPlayed = false;
|
|
|
|
_inGameHourDuration = 0;
|
|
|
|
_x = 0;
|
|
|
|
_y = 0;
|
|
|
|
_currentHourCount = 0;
|
|
|
|
_currentTime = 0;
|
|
|
|
_cfiecBuffer = nullptr;
|
|
|
|
_cfiecBufferSize = 0;
|
|
|
|
for (int i = 0; i < 601; i++) {
|
|
|
|
_dialogHintArray[i]._hintId = 0;
|
|
|
|
_dialogHintArray[i]._point = 0;
|
|
|
|
}
|
|
|
|
_currMenu = OPCODE_NONE;
|
|
|
|
_currAction = OPCODE_NONE;
|
2014-01-26 21:04:31 +01:00
|
|
|
_menuOpcode = OPCODE_NONE;
|
2014-01-24 22:44:40 +01:00
|
|
|
_addFix = 0;
|
2014-01-26 21:04:31 +01:00
|
|
|
_currBitIndex = 0;
|
|
|
|
_currDay = 0;
|
|
|
|
_currHour = 10;
|
|
|
|
_currHalfHour = 0;
|
|
|
|
_hour = 10;
|
2014-01-24 22:44:40 +01:00
|
|
|
_key = 0;
|
2014-01-26 21:04:31 +01:00
|
|
|
_manorDistance = 0;
|
|
|
|
_numpal = 0;
|
|
|
|
_savedBitIndex = 0;
|
|
|
|
_endGame = false;
|
|
|
|
_loseGame = false;
|
|
|
|
_txxFileFl = false;
|
2016-05-02 17:39:30 +02:00
|
|
|
_is = 0;
|
2011-12-31 22:53:24 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
MortevielleEngine::~MortevielleEngine() {
|
2014-01-09 08:21:52 +01:00
|
|
|
delete _menu;
|
2014-01-10 01:46:38 +01:00
|
|
|
delete _savegameManager;
|
2014-01-09 08:32:21 +01:00
|
|
|
delete _soundManager;
|
|
|
|
delete _text;
|
2014-01-09 08:21:52 +01:00
|
|
|
delete _mouse;
|
2014-01-10 01:46:38 +01:00
|
|
|
delete _screenSurface;
|
|
|
|
delete _dialogManager;
|
|
|
|
delete _debugger;
|
2014-01-09 08:21:52 +01:00
|
|
|
|
2013-07-24 18:22:35 +02:00
|
|
|
free(_curPict);
|
2013-07-25 10:32:21 +02:00
|
|
|
free(_curAnim);
|
2013-07-25 10:24:25 +02:00
|
|
|
free(_rightFramePict);
|
2011-12-31 22:53:24 +11:00
|
|
|
}
|
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
/**
|
|
|
|
* Specifies whether the engine supports given features
|
|
|
|
*/
|
2011-12-31 22:53:24 +11:00
|
|
|
bool MortevielleEngine::hasFeature(EngineFeature f) const {
|
2012-02-12 12:34:51 +11:00
|
|
|
return
|
|
|
|
(f == kSupportsRTL) ||
|
|
|
|
(f == kSupportsLoadingDuringRuntime) ||
|
|
|
|
(f == kSupportsSavingDuringRuntime);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if a game can currently be loaded
|
|
|
|
*/
|
|
|
|
bool MortevielleEngine::canLoadGameStateCurrently() {
|
|
|
|
// Saving is only allowed in the main game event loop
|
|
|
|
return _inMainGameLoop;
|
2011-12-31 22:53:24 +11:00
|
|
|
}
|
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
/**
|
|
|
|
* Return true if a game can currently be saved
|
|
|
|
*/
|
|
|
|
bool MortevielleEngine::canSaveGameStateCurrently() {
|
|
|
|
// Loading is only allowed in the main game event loop
|
|
|
|
return _inMainGameLoop;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load in a savegame at the specified slot number
|
|
|
|
*/
|
|
|
|
Common::Error MortevielleEngine::loadGameState(int slot) {
|
2014-01-10 01:46:38 +01:00
|
|
|
return _savegameManager->loadGame(slot);
|
2012-02-12 12:34:51 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Save the current game
|
|
|
|
*/
|
|
|
|
Common::Error MortevielleEngine::saveGameState(int slot, const Common::String &desc) {
|
|
|
|
if (slot == 0)
|
|
|
|
return Common::kWritingFailed;
|
2012-03-27 22:54:50 +02:00
|
|
|
|
2014-01-10 01:46:38 +01:00
|
|
|
return _savegameManager->saveGame(slot, desc);
|
2012-02-12 12:34:51 +11:00
|
|
|
}
|
|
|
|
|
2013-07-13 19:10:03 -04:00
|
|
|
/**
|
|
|
|
* Support method that generates a savegame name
|
|
|
|
* @param slot Slot number
|
|
|
|
*/
|
|
|
|
Common::String MortevielleEngine::generateSaveFilename(const Common::String &target, int slot) {
|
|
|
|
if (slot == 0)
|
|
|
|
// Initial game state loaded when the game starts
|
|
|
|
return "sav0.mor";
|
|
|
|
|
|
|
|
return Common::String::format("%s.%03d", target.c_str(), slot);
|
|
|
|
}
|
|
|
|
|
2013-09-01 22:04:20 +01:00
|
|
|
/**
|
|
|
|
* Pause the game.
|
|
|
|
*/
|
|
|
|
void MortevielleEngine::pauseEngineIntern(bool pause) {
|
|
|
|
Engine::pauseEngineIntern(pause);
|
|
|
|
if (pause) {
|
|
|
|
if (_pauseStartTime == -1)
|
|
|
|
_pauseStartTime = readclock();
|
|
|
|
} else {
|
|
|
|
if (_pauseStartTime != -1) {
|
|
|
|
int pauseEndTime = readclock();
|
|
|
|
_currentTime += (pauseEndTime - _pauseStartTime);
|
|
|
|
if (_uptodatePresence)
|
|
|
|
_startTime += (pauseEndTime - _pauseStartTime);
|
|
|
|
}
|
|
|
|
_pauseStartTime = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
/**
|
2013-07-19 10:59:20 +02:00
|
|
|
* Initialize the game state
|
2012-02-12 12:34:51 +11:00
|
|
|
*/
|
2013-07-19 10:59:20 +02:00
|
|
|
Common::ErrorCode MortevielleEngine::initialize() {
|
|
|
|
// Initialize graphics mode
|
2017-10-01 00:56:01 -05:00
|
|
|
initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT);
|
2012-01-03 20:47:05 +11:00
|
|
|
|
2012-01-05 07:56:45 +11:00
|
|
|
// Set up an intermediate screen surface
|
2014-01-10 01:46:38 +01:00
|
|
|
_screenSurface->create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
|
2012-01-05 07:56:45 +11:00
|
|
|
|
2012-02-26 02:04:25 +01:00
|
|
|
_txxFileFl = false;
|
|
|
|
// Load texts from TXX files
|
2012-03-22 00:13:11 +01:00
|
|
|
loadTexts();
|
2012-02-26 02:04:25 +01:00
|
|
|
|
2012-01-05 07:56:45 +11:00
|
|
|
// Load the mort.dat resource
|
2012-01-20 16:31:15 +11:00
|
|
|
Common::ErrorCode result = loadMortDat();
|
2013-06-30 13:45:43 -06:00
|
|
|
if (result != Common::kNoError) {
|
2014-01-10 01:46:38 +01:00
|
|
|
_screenSurface->free();
|
2012-01-20 16:31:15 +11:00
|
|
|
return result;
|
2013-06-30 13:45:43 -06:00
|
|
|
}
|
2012-01-20 16:31:15 +11:00
|
|
|
|
2012-02-26 02:04:25 +01:00
|
|
|
// Load some error messages (was previously in chartex())
|
2012-03-21 08:32:36 +01:00
|
|
|
_hintPctMessage = getString(580); // You should have noticed %d hints
|
2012-02-26 02:04:25 +01:00
|
|
|
|
2012-01-20 16:31:15 +11:00
|
|
|
// Set default EGA palette
|
|
|
|
_paletteManager.setDefaultPalette();
|
|
|
|
|
|
|
|
// Setup the mouse cursor
|
|
|
|
initMouse();
|
|
|
|
|
2012-03-22 00:13:11 +01:00
|
|
|
loadPalette();
|
2012-03-09 22:25:28 +01:00
|
|
|
loadCFIPH();
|
|
|
|
loadCFIEC();
|
2012-03-29 12:49:25 +02:00
|
|
|
decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
|
2012-10-10 08:19:54 +02:00
|
|
|
_x26KeyCount = 1;
|
2013-07-23 10:51:42 +02:00
|
|
|
initMaxAnswer();
|
2012-02-19 21:15:57 +01:00
|
|
|
initMouse();
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2012-03-11 23:06:33 +01:00
|
|
|
loadPlaces();
|
2012-03-08 08:24:54 +01:00
|
|
|
_soundOff = false;
|
|
|
|
_largestClearScreen = false;
|
2012-02-12 22:54:41 +11:00
|
|
|
|
2012-03-24 22:00:28 +01:00
|
|
|
testKeyboard();
|
2012-03-22 00:13:11 +01:00
|
|
|
showConfigScreen();
|
2012-03-24 22:00:28 +01:00
|
|
|
testKeyboard();
|
2013-08-14 08:17:37 +02:00
|
|
|
clearScreen();
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2014-01-09 08:32:21 +01:00
|
|
|
_soundManager->loadNoise();
|
|
|
|
_soundManager->loadAmbiantSounds();
|
2013-08-10 22:17:10 +02:00
|
|
|
|
2012-01-20 16:31:15 +11:00
|
|
|
return Common::kNoError;
|
2012-01-05 07:56:45 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-07-13 22:10:21 +02:00
|
|
|
* Loads the contents of the mort.dat data file
|
2012-01-05 07:56:45 +11:00
|
|
|
*/
|
|
|
|
Common::ErrorCode MortevielleEngine::loadMortDat() {
|
|
|
|
Common::File f;
|
|
|
|
|
|
|
|
// Open the mort.dat file
|
|
|
|
if (!f.open(MORT_DAT)) {
|
2018-12-19 06:31:26 +00:00
|
|
|
GUIErrorMessageFormat(_("Unable to locate the '%s' engine data file."), MORT_DAT);
|
2012-01-05 07:56:45 +11:00
|
|
|
return Common::kReadingFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate the data file header
|
|
|
|
char fileId[4];
|
|
|
|
f.read(fileId, 4);
|
|
|
|
if (strncmp(fileId, "MORT", 4) != 0) {
|
2018-12-19 06:31:26 +00:00
|
|
|
GUIErrorMessageFormat(_("The '%s' engine data file is corrupt."), MORT_DAT);
|
2012-01-05 07:56:45 +11:00
|
|
|
return Common::kReadingFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the version
|
2016-12-06 09:25:00 +01:00
|
|
|
int majVer = f.readByte();
|
|
|
|
int minVer = f.readByte();
|
|
|
|
|
|
|
|
if (majVer < MORT_DAT_REQUIRED_VERSION) {
|
2018-12-19 06:31:26 +00:00
|
|
|
GUIErrorMessageFormat(
|
2016-12-08 10:22:47 +01:00
|
|
|
_("Incorrect version of the '%s' engine data file found. Expected %d.%d but got %d.%d."),
|
2016-12-06 09:25:00 +01:00
|
|
|
MORT_DAT, MORT_DAT_REQUIRED_VERSION, 0, majVer, minVer);
|
2012-01-05 07:56:45 +11:00
|
|
|
return Common::kReadingFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop to load resources from the data file
|
|
|
|
while (f.pos() < f.size()) {
|
|
|
|
// Get the Id and size of the next resource
|
|
|
|
char dataType[4];
|
|
|
|
int dataSize;
|
|
|
|
f.read(dataType, 4);
|
|
|
|
dataSize = f.readUint16LE();
|
|
|
|
|
|
|
|
if (!strncmp(dataType, "FONT", 4)) {
|
|
|
|
// Font resource
|
2014-01-10 01:46:38 +01:00
|
|
|
_screenSurface->readFontData(f, dataSize);
|
2012-02-12 19:40:03 +11:00
|
|
|
} else if (!strncmp(dataType, "SSTR", 4)) {
|
2012-02-26 02:04:25 +01:00
|
|
|
readStaticStrings(f, dataSize, kStaticStrings);
|
|
|
|
} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
|
|
|
|
readStaticStrings(f, dataSize, kGameStrings);
|
2013-08-15 07:57:07 +02:00
|
|
|
} else if (!strncmp(dataType, "VERB", 4)) {
|
2014-01-09 08:21:52 +01:00
|
|
|
_menu->readVerbNums(f, dataSize);
|
2012-01-05 07:56:45 +11:00
|
|
|
} else {
|
|
|
|
// Unknown section
|
|
|
|
f.skip(dataSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-12 19:40:03 +11:00
|
|
|
// Close the file
|
2012-01-05 07:56:45 +11:00
|
|
|
f.close();
|
2012-02-12 19:40:03 +11:00
|
|
|
|
2012-02-25 21:13:24 +01:00
|
|
|
assert(_engineStrings.size() > 0);
|
2012-01-05 07:56:45 +11:00
|
|
|
return Common::kNoError;
|
|
|
|
}
|
|
|
|
|
2013-08-15 07:57:07 +02:00
|
|
|
|
2012-02-12 19:40:03 +11:00
|
|
|
/**
|
|
|
|
* Read in a static strings block, and if the language matches, load up the static strings
|
|
|
|
*/
|
2012-02-26 02:04:25 +01:00
|
|
|
void MortevielleEngine::readStaticStrings(Common::File &f, int dataSize, DataType dataType) {
|
2012-02-12 19:40:03 +11:00
|
|
|
// Figure out what language Id is needed
|
2012-03-29 12:40:49 +02:00
|
|
|
byte desiredLanguageId;
|
|
|
|
switch(getLanguage()) {
|
|
|
|
case Common::EN_ANY:
|
2013-07-30 20:53:07 +01:00
|
|
|
desiredLanguageId = MORTDAT_LANG_ENGLISH;
|
2012-03-29 12:40:49 +02:00
|
|
|
break;
|
|
|
|
case Common::FR_FRA:
|
2013-07-30 20:53:07 +01:00
|
|
|
desiredLanguageId = MORTDAT_LANG_FRENCH;
|
2012-03-29 12:40:49 +02:00
|
|
|
break;
|
|
|
|
case Common::DE_DEU:
|
2013-07-30 20:53:07 +01:00
|
|
|
desiredLanguageId = MORTDAT_LANG_GERMAN;
|
2012-03-29 12:40:49 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
warning("Language not supported, switching to English");
|
2013-07-30 20:53:07 +01:00
|
|
|
desiredLanguageId = MORTDAT_LANG_ENGLISH;
|
2012-03-29 12:40:49 +02:00
|
|
|
break;
|
|
|
|
}
|
2012-02-12 19:40:03 +11:00
|
|
|
|
|
|
|
// Read in the language
|
|
|
|
byte languageId = f.readByte();
|
|
|
|
--dataSize;
|
|
|
|
|
|
|
|
// If the language isn't correct, then skip the entire block
|
|
|
|
if (languageId != desiredLanguageId) {
|
|
|
|
f.skip(dataSize);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load in each of the strings
|
|
|
|
while (dataSize > 0) {
|
|
|
|
Common::String s;
|
|
|
|
char ch;
|
|
|
|
while ((ch = (char)f.readByte()) != '\0')
|
|
|
|
s += ch;
|
2012-03-27 22:54:50 +02:00
|
|
|
|
2012-02-26 02:04:25 +01:00
|
|
|
if (dataType == kStaticStrings)
|
|
|
|
_engineStrings.push_back(s);
|
|
|
|
else if (dataType == kGameStrings)
|
|
|
|
_gameStrings.push_back(s);
|
|
|
|
|
2012-02-12 19:40:03 +11:00
|
|
|
dataSize -= s.size() + 1;
|
|
|
|
}
|
|
|
|
assert(dataSize == 0);
|
|
|
|
}
|
|
|
|
|
2012-01-05 07:56:45 +11:00
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
Common::Error MortevielleEngine::run() {
|
2013-07-19 10:59:20 +02:00
|
|
|
// Initialize the game
|
|
|
|
Common::ErrorCode err = initialize();
|
2012-01-05 07:56:45 +11:00
|
|
|
if (err != Common::kNoError)
|
|
|
|
return err;
|
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
// Check for a savegame
|
|
|
|
int loadSlot = 0;
|
|
|
|
if (ConfMan.hasKey("save_slot")) {
|
|
|
|
int gameToLoad = ConfMan.getInt("save_slot");
|
2012-02-21 22:36:45 +01:00
|
|
|
if ((gameToLoad >= 1) && (gameToLoad <= 999))
|
2012-02-12 12:34:51 +11:00
|
|
|
loadSlot = gameToLoad;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loadSlot == 0)
|
|
|
|
// Show the game introduction
|
|
|
|
showIntroduction();
|
2013-08-20 23:09:34 +02:00
|
|
|
else {
|
|
|
|
_caff = 51;
|
2014-01-09 08:32:21 +01:00
|
|
|
_text->taffich();
|
2013-08-20 23:09:34 +02:00
|
|
|
}
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
// Either load the initial game state savegame, or the specified savegame number
|
2012-02-07 22:40:06 +11:00
|
|
|
adzon();
|
2013-08-20 23:09:34 +02:00
|
|
|
resetVariables();
|
2013-08-16 23:29:52 +02:00
|
|
|
if (loadSlot != 0)
|
2014-01-10 01:46:38 +01:00
|
|
|
_savegameManager->loadSavegame(generateSaveFilename(loadSlot));
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
// Run the main game loop
|
2012-02-07 22:40:06 +11:00
|
|
|
mainGame();
|
2013-07-23 09:13:32 +02:00
|
|
|
|
2013-07-19 10:59:20 +02:00
|
|
|
// Cleanup (allocated in initialize())
|
2014-01-10 01:46:38 +01:00
|
|
|
_screenSurface->free();
|
2014-01-09 08:32:21 +01:00
|
|
|
free(_soundManager->_cfiphBuffer);
|
2013-06-30 13:45:43 -06:00
|
|
|
free(_cfiecBuffer);
|
2011-12-31 22:53:24 +11:00
|
|
|
|
|
|
|
return Common::kNoError;
|
|
|
|
}
|
|
|
|
|
2012-02-07 22:40:06 +11:00
|
|
|
/**
|
|
|
|
* Show the game introduction
|
|
|
|
*/
|
|
|
|
void MortevielleEngine::showIntroduction() {
|
2014-01-10 01:46:38 +01:00
|
|
|
_dialogManager->displayIntroScreen(false);
|
|
|
|
_dialogManager->checkForF8(142, false);
|
2013-06-26 07:51:11 +02:00
|
|
|
if (shouldQuit())
|
2013-06-24 23:48:00 +02:00
|
|
|
return;
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2014-01-10 01:46:38 +01:00
|
|
|
_dialogManager->displayIntroFrame2();
|
|
|
|
_dialogManager->checkForF8(143, true);
|
2013-06-26 07:51:11 +02:00
|
|
|
if (shouldQuit())
|
2013-06-24 23:48:00 +02:00
|
|
|
return;
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2012-03-22 00:13:11 +01:00
|
|
|
showTitleScreen();
|
2012-02-07 22:40:06 +11:00
|
|
|
music();
|
2013-08-04 10:39:34 +02:00
|
|
|
_mixer->stopAll();
|
2012-02-07 22:40:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-02-12 14:22:56 +11:00
|
|
|
* Main game loop. Handles potentially playing the game multiple times, such as if the player
|
|
|
|
* loses, and chooses to start playing the game again.
|
2012-02-07 22:40:06 +11:00
|
|
|
*/
|
|
|
|
void MortevielleEngine::mainGame() {
|
2012-03-09 22:25:28 +01:00
|
|
|
if (_reloadCFIEC)
|
|
|
|
loadCFIEC();
|
2012-02-21 22:36:45 +01:00
|
|
|
|
2012-10-10 08:19:54 +02:00
|
|
|
for (_crep = 1; _crep <= _x26KeyCount; ++_crep)
|
2013-02-25 23:22:07 +01:00
|
|
|
decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
|
2012-02-21 22:36:45 +01:00
|
|
|
|
2014-01-09 08:21:52 +01:00
|
|
|
_menu->initMenu();
|
2012-02-07 22:40:06 +11:00
|
|
|
|
2012-03-18 09:44:05 +01:00
|
|
|
charToHour();
|
2012-03-13 00:06:15 +01:00
|
|
|
initGame();
|
2013-08-14 08:17:37 +02:00
|
|
|
clearScreen();
|
2012-03-12 01:26:02 +01:00
|
|
|
drawRightFrame();
|
2014-01-09 08:21:52 +01:00
|
|
|
_mouse->showMouse();
|
2012-02-12 14:22:56 +11:00
|
|
|
|
|
|
|
// Loop to play the game
|
2012-02-07 22:40:06 +11:00
|
|
|
do {
|
2012-02-12 14:22:56 +11:00
|
|
|
playGame();
|
2013-06-26 07:51:11 +02:00
|
|
|
if (shouldQuit())
|
2013-06-24 23:48:00 +02:00
|
|
|
return;
|
2012-02-12 14:22:56 +11:00
|
|
|
} while (!_quitGame);
|
2012-02-07 22:40:06 +11:00
|
|
|
}
|
|
|
|
|
2012-02-12 12:34:51 +11:00
|
|
|
/**
|
2012-02-12 14:22:56 +11:00
|
|
|
* This method handles playing a loaded game
|
2012-03-10 14:17:05 +01:00
|
|
|
* @remarks Originally called tjouer
|
2012-02-12 12:34:51 +11:00
|
|
|
*/
|
2012-02-12 14:22:56 +11:00
|
|
|
void MortevielleEngine::playGame() {
|
|
|
|
gameLoaded();
|
|
|
|
|
|
|
|
// Loop handling actions until the game has to be quit, or show the lose or end sequence
|
2012-02-12 12:34:51 +11:00
|
|
|
do {
|
2012-02-12 14:22:56 +11:00
|
|
|
handleAction();
|
2013-06-26 07:51:11 +02:00
|
|
|
if (shouldQuit())
|
2013-06-24 23:48:00 +02:00
|
|
|
return;
|
2012-02-12 14:22:56 +11:00
|
|
|
} while (!((_quitGame) || (_endGame) || (_loseGame)));
|
2012-02-21 22:36:45 +01:00
|
|
|
|
2012-02-12 14:22:56 +11:00
|
|
|
if (_endGame)
|
|
|
|
endGame();
|
|
|
|
else if (_loseGame)
|
2012-03-14 18:25:17 +01:00
|
|
|
askRestart();
|
2012-02-12 12:34:51 +11:00
|
|
|
}
|
|
|
|
|
2011-12-31 22:53:24 +11:00
|
|
|
} // End of namespace Mortevielle
|