aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorStrangerke2013-06-27 20:19:27 +0200
committerStrangerke2013-06-27 20:19:27 +0200
commit1e2a9900f21daed825dd5498bb51868bd0714a1a (patch)
tree481e164dd53e018d94a6b5506ff1f3abdbc1a1bc /engines
parentb770e315264cf97f5a673499514eb573b54676bb (diff)
downloadscummvm-rg350-1e2a9900f21daed825dd5498bb51868bd0714a1a.tar.gz
scummvm-rg350-1e2a9900f21daed825dd5498bb51868bd0714a1a.tar.bz2
scummvm-rg350-1e2a9900f21daed825dd5498bb51868bd0714a1a.zip
MORTEVIELLE: Move misc functions from Mortevielle to Utils
Diffstat (limited to 'engines')
-rw-r--r--engines/mortevielle/module.mk3
-rw-r--r--engines/mortevielle/mortevielle.cpp3417
-rw-r--r--engines/mortevielle/utils.cpp3454
3 files changed, 3456 insertions, 3418 deletions
diff --git a/engines/mortevielle/module.mk b/engines/mortevielle/module.mk
index 9cce597566..e18657cb6a 100644
--- a/engines/mortevielle/module.mk
+++ b/engines/mortevielle/module.mk
@@ -12,7 +12,8 @@ MODULE_OBJS := \
outtext.o \
saveload.o \
sound.o \
- speech.o
+ speech.o \
+ utils.o
# This module can be built as a plugin
ifeq ($(ENABLE_MORTEVIELLE), DYNAMIC_PLUGIN)
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 95750f5c4a..6977ab47c0 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -30,7 +30,6 @@
#include "common/debug-channels.h"
#include "engines/util.h"
#include "engines/engine.h"
-#include "graphics/cursorman.h"
#include "graphics/palette.h"
#include "graphics/pixelformat.h"
#include "mortevielle/mortevielle.h"
@@ -43,31 +42,6 @@
namespace Mortevielle {
-const byte tabdr[32] = {
- 32, 101, 115, 97, 114, 105, 110,
- 117, 116, 111, 108, 13, 100, 99,
- 112, 109, 46, 118, 130, 39, 102,
- 98, 44, 113, 104, 103, 33, 76,
- 85, 106, 30, 31
-};
-
-
-const byte tab30[32] = {
- 69, 67, 74, 138, 133, 120, 77, 122,
- 121, 68, 65, 63, 73, 80, 83, 82,
- 156, 45, 58, 79, 49, 86, 78, 84,
- 71, 81, 64, 66, 135, 34, 136, 91
-};
-
-
-
-const byte tab31[32]= {
- 93, 47, 48, 53, 50, 70, 124, 75,
- 72, 147, 140, 150, 151, 57, 56, 51,
- 107, 139, 55, 89, 131, 37, 54, 88,
- 119, 0, 0, 0, 0, 0, 0, 0
-};
-
MortevielleEngine *g_vm;
MortevielleEngine::MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc):
@@ -339,213 +313,6 @@ void MortevielleEngine::readStaticStrings(Common::File &f, int dataSize, DataTyp
assert(dataSize == 0);
}
-/**
- * Check is a key was pressed
- * It also delays the engine and check if the screen has to be updated
- * @remarks Originally called 'keypressed'
- */
-bool MortevielleEngine::keyPressed() {
- // Check for any pending key presses
- handleEvents();
-
- // Check if it's time to draw the next frame
- if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
- _lastGameFrame = g_system->getMillis();
-
- _screenSurface.updateScreen();
-
- _debugger.onFrame();
- }
-
- // Delay briefly to keep CPU usage down
- g_system->delayMillis(5);
-
- // Return if there are any pending key presses
- return !_keypresses.empty();
-}
-
-/**
- * Wait for a keypress
- * @remarks Originally called 'get_ch'
- */
-int MortevielleEngine::getChar() {
- // If there isn't any pending keypress, wait until there is
- while (!shouldQuit() && _keypresses.empty()) {
- keyPressed();
- }
-
- // Return the top keypress
- return shouldQuit() ? 0 : _keypresses.pop();
-}
-
-/**
- * Handle pending events
- * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
- * the mouse Y position is divided by 2 to keep the game thinking the Y goes from 0 - 199
- */
-bool MortevielleEngine::handleEvents() {
- Common::Event event;
- if (!g_system->getEventManager()->pollEvent(event))
- return false;
-
- switch (event.type) {
- case Common::EVENT_LBUTTONDOWN:
- case Common::EVENT_LBUTTONUP:
- case Common::EVENT_MOUSEMOVE:
- _mousePos = Common::Point(event.mouse.x, event.mouse.y / 2);
- _mouse._pos.x = event.mouse.x;
- _mouse._pos.y = event.mouse.y / 2;
-
- if (event.type == Common::EVENT_LBUTTONDOWN)
- _mouseClick = true;
- else if (event.type == Common::EVENT_LBUTTONUP)
- _mouseClick = false;
-
- break;
- case Common::EVENT_KEYDOWN:
- addKeypress(event);
- break;
- default:
- break;
- }
-
- return true;
-}
-
-/**
- * Add the specified key to the pending keypress stack
- */
-void MortevielleEngine::addKeypress(Common::Event &evt) {
- // Character to add
- char ch = evt.kbd.ascii;
-
- // Check for debugger
- if ((evt.kbd.keycode == Common::KEYCODE_d) && (evt.kbd.flags & Common::KBD_CTRL)) {
- // Attach to the debugger
- _debugger.attach();
- _debugger.onFrame();
- } else if ((evt.kbd.keycode >= Common::KEYCODE_a) && (evt.kbd.keycode <= Common::KEYCODE_z)) {
- // Handle alphabetic keys
- if (evt.kbd.hasFlags(Common::KBD_CTRL))
- ch = evt.kbd.keycode - Common::KEYCODE_a + 1;
- else
- ch = evt.kbd.keycode - Common::KEYCODE_a + 'A';
- } else if ((evt.kbd.keycode >= Common::KEYCODE_F1) && (evt.kbd.keycode <= Common::KEYCODE_F12)) {
- // Handle function keys
- ch = 59 + evt.kbd.keycode - Common::KEYCODE_F1;
- } else {
- // Series of special cases
- switch (evt.kbd.keycode) {
- case Common::KEYCODE_KP4:
- case Common::KEYCODE_LEFT:
- ch = '4';
- break;
- case Common::KEYCODE_KP2:
- case Common::KEYCODE_DOWN:
- ch = '2';
- break;
- case Common::KEYCODE_KP6:
- case Common::KEYCODE_RIGHT:
- ch = '6';
- break;
- case Common::KEYCODE_KP8:
- case Common::KEYCODE_UP:
- ch = '8';
- break;
- case Common::KEYCODE_KP7:
- ch = '7';
- break;
- case Common::KEYCODE_KP1:
- ch = '1';
- break;
- case Common::KEYCODE_KP9:
- ch = '9';
- break;
- case Common::KEYCODE_KP3:
- ch = '3';
- break;
- case Common::KEYCODE_KP5:
- ch = '5';
- break;
- case Common::KEYCODE_RETURN:
- ch = '\13';
- break;
- case Common::KEYCODE_ESCAPE:
- ch = '\33';
- break;
- default:
- break;
- }
- }
-
- if (ch != 0)
- _keypresses.push(ch);
-}
-
-static byte CURSOR_ARROW_DATA[16 * 16] = {
- 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x0f, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-};
-
-/**
- * Initialise the mouse
- */
-void MortevielleEngine::initMouse() {
- CursorMan.replaceCursor(CURSOR_ARROW_DATA, 16, 16, 0, 0, 0xff);
- CursorMan.showMouse(true);
-
- _mouse.initMouse();
-}
-
-/**
- * Sets the mouse position
- * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
- * the mouse Y position is doubled to convert from 0-199 to 0-399
- */
-void MortevielleEngine::setMousePos(const Common::Point &pt) {
- // Adjust the passed position from simulated 640x200 to 640x400 co-ordinates
- Common::Point newPoint(pt.x, (pt.y == 199) ? 399 : pt.y * 2);
-
- if (newPoint != _mousePos)
- // Warp the mouse to the new position
- g_system->warpMouse(newPoint.x, newPoint.y);
-
- // Save the new position
- _mousePos = newPoint;
-}
-
-/**
- * Delay by a given amount
- */
-void MortevielleEngine::delay(int amount) {
- uint32 endTime = g_system->getMillis() + amount;
-
- while (g_system->getMillis() < endTime) {
- if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
- _lastGameFrame = g_system->getMillis();
- _screenSurface.updateScreen();
-
- _debugger.onFrame();
- }
-
- g_system->delayMillis(10);
- }
-}
-
/*-------------------------------------------------------------------------*/
Common::Error MortevielleEngine::run() {
@@ -645,3188 +412,4 @@ void MortevielleEngine::playGame() {
askRestart();
}
-/**
- * Waits for the user to select an action, and then handles it
- * @remarks Originally called tecran
- */
-void MortevielleEngine::handleAction() {
- const int lim = 20000;
- int temps = 0;
- char inkey = '\0';
- bool oo, funct = 0;
-
- clearVerbBar();
- oo = false;
- _controlMenu = 0;
- if (!_keyPressedEsc) {
- _menu.drawMenu();
- _menu._menuDisplayed = true;
- temps = 0;
- _key = 0;
- funct = false;
- inkey = '.';
-
- _inMainGameLoop = true;
- do {
- _menu.updateMenu();
- prepareRoom();
- _mouse.moveMouse(funct, inkey);
- if (shouldQuit())
- return;
- ++temps;
- } while (!((_menu._menuSelected) || (temps > lim) || (funct) || (_anyone)));
- _inMainGameLoop = false;
-
- _menu.eraseMenu();
- _menu._menuDisplayed = false;
- if ((inkey == '\1') || (inkey == '\3') || (inkey == '\5') || (inkey == '\7') || (inkey == '\11')) {
- changeGraphicalDevice((uint)(ord(inkey) - 1) >> 1);
- return;
- }
- if (_menu._menuSelected && (_msg[3] == MENU_SAVE)) {
- Common::String saveName = Common::String::format("Savegame #%d", _msg[4] & 15);
- _savegameManager.saveGame(_msg[4] & 15, saveName);
- }
- if (_menu._menuSelected && (_msg[3] == MENU_LOAD))
- _savegameManager.loadGame((_msg[4] & 15) - 1);
- if (inkey == '\103') { /* F9 */
- temps = _dialogManager.show(_hintPctMessage, 1);
- return;
- } else if (inkey == '\77') {
- if ((_menuOpcode != OPCODE_NONE) && ((_msg[3] == MENU_ACTION) || (_msg[3] == MENU_SELF))) {
- _msg[4] = _menuOpcode;
- displayTextInVerbBar(getEngineString(S_IDEM));
- } else
- return;
- } else if (inkey == '\104') {
- if ((_x != 0) && (_y != 0))
- _num = 9999;
- return;
- }
- }
- if (inkey == '\73') {
- _quitGame = true;
- hourToChar();
- } else {
- if ((funct) && (inkey != '\77'))
- return;
- if (temps > lim) {
- handleDescriptionText(2, 141);
- if (_num == 9999)
- _num = 0;
- } else {
- _menuOpcode = _msg[3];
- if ((_msg[3] == MENU_ACTION) || (_msg[3] == MENU_SELF))
- _menuOpcode = _msg[4];
- if (!_anyone) {
- if ((_heroSearching) || (_obpart)) {
- if (_mouse._pos.y < 12)
- return;
-
- if ((_msg[4] == OPCODE_SOUND) || (_msg[4] == OPCODE_LIFT)) {
- oo = true;
- if ((_msg[4] == OPCODE_LIFT) || (_obpart)) {
- endSearch();
- _caff = _coreVar._currPlace;
- _crep = 998;
- } else
- tsuiv();
- mennor();
- }
- }
- }
- do {
- if (! oo)
- handleOpcode();
-
- if ((_controlMenu == 0) && (! _loseGame) && (! _endGame)) {
- _text.taffich();
- if (_destinationOk) {
- _destinationOk = false;
- drawPicture();
- }
- if ((!_syn) || (_col))
- handleDescriptionText(2, _crep);
- }
- } while (_syn);
- if (_controlMenu != 0)
- displayControlMenu();
- }
- }
-}
-
-/**
- * Engine function - Init Places
- * @remarks Originally called 'init_lieu'
- */
-void MortevielleEngine::loadPlaces() {
- Common::File f;
-
- if (!f.open("MXX.mor"))
- if (!f.open("MFXX.mor"))
- error("Missing file - MXX.mor");
-
- for (int i = 0; i < 7; ++i) {
- for (int j = 0; j < 25; ++j)
- _destinationArray[i][j] = f.readByte();
- }
-
- f.close();
-}
-
-/**
- * Set Text Color
- * @remarks Originally called 'text_color'
- */
-void MortevielleEngine::setTextColor(int col) {
- _textColor = col;
-}
-
-/**
- * Prepare screen - Type 1!
- * @remarks Originally called 'ecrf1'
- */
-void MortevielleEngine::prepareScreenType1() {
- // Large drawing
- _screenSurface.drawBox(0, 11, 512, 163, 15);
-}
-
-/**
- * Prepare room - Type 2!
- * @remarks Originally called 'ecrf2'
- */
-void MortevielleEngine::prepareScreenType2() {
- setTextColor(5);
-}
-
-/**
- * Prepare room - Type 3!
- * @remarks Originally called 'ecrf7'
- */
-void MortevielleEngine::prepareScreenType3() {
- setTextColor(4);
-}
-
-/**
- * Engine function - Update hour
- * @remarks Originally called 'calch'
- */
-void MortevielleEngine::updateHour(int &day, int &hour, int &minute) {
- int newHour = readclock();
- int th = _currentHourCount + ((newHour - _currentDayHour) / _inGameHourDuration);
- minute = ((th % 2) + _currHalfHour) * 30;
- hour = ((uint)th >> 1) + _currHour;
- if (minute == 60) {
- minute = 0;
- ++hour;
- }
- day = (hour / 24) + _currDay;
- hour = hour - ((day - _currDay) * 24);
-}
-
-/**
- * Engine function - Convert character index to bit index
- * @remarks Originally called 'conv'
- */
-int MortevielleEngine::convertCharacterIndexToBitIndex(int characterIndex) {
- return 128 >> (characterIndex - 1);
-}
-
-/**
- * Engine function - Convert bit index to character index
- * @remarks Originally called 'tip'
- */
-int MortevielleEngine::convertBitIndexToCharacterIndex(int bitIndex) {
- int retVal = 0;
-
- if (bitIndex == 128)
- retVal = 1;
- else if (bitIndex == 64)
- retVal = 2;
- else if (bitIndex == 32)
- retVal = 3;
- else if (bitIndex == 16)
- retVal = 4;
- else if (bitIndex == 8)
- retVal = 5;
- else if (bitIndex == 4)
- retVal = 6;
- else if (bitIndex == 2)
- retVal = 7;
- else if (bitIndex == 1)
- retVal = 8;
-
- return retVal;
-}
-
-/**
- * Engine function - Reset presence in other rooms
- * @remarks Originally called 't5'
- */
-void MortevielleEngine::resetPresenceInRooms(int roomId) {
- if (roomId == DINING_ROOM)
- _blo = false;
-
- if (roomId != GREEN_ROOM) {
- _roomPresenceLuc = false;
- _roomPresenceIda = false;
- }
-
- if (roomId != PURPLE_ROOM)
- _purpleRoomPresenceLeo = false;
-
- if (roomId != DARKBLUE_ROOM) {
- _roomPresenceGuy = false;
- _roomPresenceEva = false;
- }
-
- if (roomId != BLUE_ROOM)
- _roomPresenceMax = false;
- if (roomId != RED_ROOM)
- _roomPresenceBob = false;
- if (roomId != GREEN_ROOM2)
- _roomPresencePat = false;
- if (roomId != TOILETS)
- _toiletsPresenceBobMax = false;
- if (roomId != BATHROOM)
- _bathRoomPresenceBobMax = false;
- if (roomId != ROOM9)
- _room9PresenceLeo = false;
-}
-
-/**
- * Engine function - Show the people present in the given room
- * @remarks Originally called 'affper'
- */
-void MortevielleEngine::showPeoplePresent(int bitIndex) {
- int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
-
- for (int i = 1; i <= 8; ++i)
- _menu.disableMenuItem(_menu._discussMenu[i]);
-
- clearUpperRightPart();
- if ((bitIndex & 128) == 128) {
- _screenSurface.putxy(xp, 24);
- _screenSurface.drawString("LEO", 4);
- _menu.enableMenuItem(_menu._discussMenu[1]);
- }
- if ((bitIndex & 64) == 64) {
- _screenSurface.putxy(xp, 32);
- _screenSurface.drawString("PAT", 4);
- _menu.enableMenuItem(_menu._discussMenu[2]);
- }
- if ((bitIndex & 32) == 32) {
- _screenSurface.putxy(xp, 40);
- _screenSurface.drawString("GUY", 4);
- _menu.enableMenuItem(_menu._discussMenu[3]);
- }
- if ((bitIndex & 16) == 16) {
- _screenSurface.putxy(xp, 48);
- _screenSurface.drawString("EVA", 4);
- _menu.enableMenuItem(_menu._discussMenu[4]);
- }
- if ((bitIndex & 8) == 8) {
- _screenSurface.putxy(xp, 56);
- _screenSurface.drawString("BOB", 4);
- _menu.enableMenuItem(_menu._discussMenu[5]);
- }
- if ((bitIndex & 4) == 4) {
- _screenSurface.putxy(xp, 64);
- _screenSurface.drawString("LUC", 4);
- _menu.enableMenuItem(_menu._discussMenu[6]);
- }
- if ((bitIndex & 2) == 2) {
- _screenSurface.putxy(xp, 72);
- _screenSurface.drawString("IDA", 4);
- _menu.enableMenuItem(_menu._discussMenu[7]);
- }
- if ((bitIndex & 1) == 1) {
- _screenSurface.putxy(xp, 80);
- _screenSurface.drawString("MAX", 4);
- _menu.enableMenuItem(_menu._discussMenu[8]);
- }
- _currBitIndex = bitIndex;
-}
-
-/**
- * Engine function - Select random characters
- * @remarks Originally called 'choix'
- */
-int MortevielleEngine::selectCharacters(int min, int max) {
- bool invertSelection = false;
- int rand = getRandomNumber(min, max);
-
- if (rand > 4) {
- rand = 8 - rand;
- invertSelection = true;
- }
-
- int i = 0;
- int retVal = 0;
- while (i < rand) {
- int charIndex = getRandomNumber(1, 8);
- int charBitIndex = convertCharacterIndexToBitIndex(charIndex);
- if ((retVal & charBitIndex) != charBitIndex) {
- ++i;
- retVal |= charBitIndex;
- }
- }
- if (invertSelection)
- retVal = 255 - retVal;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Green Room
- * @remarks Originally called 'cpl1'
- */
-int MortevielleEngine::getPresenceStatsGreenRoom() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- // The original uses an || instead of an &&, resulting
- // in an always true condition. Based on the other tests,
- // and on other scenes, we use an && instead.
- if ((hour > 7) && (hour < 11))
- retVal = 25;
- else if ((hour > 10) && (hour < 14))
- retVal = 35;
- else if ((hour > 13) && (hour < 16))
- retVal = 50;
- else if ((hour > 15) && (hour < 18))
- retVal = 5;
- else if ((hour > 17) && (hour < 22))
- retVal = 35;
- else if ((hour > 21) && (hour < 24))
- retVal = 50;
- else if ((hour >= 0) && (hour < 8))
- retVal = 70;
-
- _menu.updateMenu();
-
- return retVal;
-}
-/**
- * Engine function - Get Presence Statistics - Purple Room
- * @remarks Originally called 'cpl2'
- */
-int MortevielleEngine::getPresenceStatsPurpleRoom() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if ((hour > 7) && (hour < 11))
- retVal = -2;
- else if (hour == 11)
- retVal = 100;
- else if ((hour > 11) && (hour < 23))
- retVal = 10;
- else if (hour == 23)
- retVal = 20;
- else if ((hour >= 0) && (hour < 8))
- retVal = 50;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Toilets
- * @remarks Originally called 'cpl3'
- */
-int MortevielleEngine::getPresenceStatsToilets() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if (((hour > 8) && (hour < 10)) || ((hour > 19) && (hour < 24)))
- retVal = 34;
- else if (((hour > 9) && (hour < 20)) || ((hour >= 0) && (hour < 9)))
- retVal = 0;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Blue Room
- * @remarks Originally called 'cpl5'
- */
-int MortevielleEngine::getPresenceStatsBlueRoom() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if ((hour > 6) && (hour < 10))
- retVal = 0;
- else if (hour == 10)
- retVal = 100;
- else if ((hour > 10) && (hour < 24))
- retVal = 15;
- else if ((hour >= 0) && (hour < 7))
- retVal = 50;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Red Room
- * @remarks Originally called 'cpl6'
- */
-int MortevielleEngine::getPresenceStatsRedRoom() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if (((hour > 7) && (hour < 13)) || ((hour > 17) && (hour < 20)))
- retVal = -2;
- else if (((hour > 12) && (hour < 17)) || ((hour > 19) && (hour < 24)))
- retVal = 35;
- else if (hour == 17)
- retVal = 100;
- else if ((hour >= 0) && (hour < 8))
- retVal = 60;
-
- return retVal;
-}
-
-/**
- * Shows the "you are alone" message in the status area
- * on the right hand side of the screen
- * @remarks Originally called 'person'
- */
-void MortevielleEngine::displayAloneText() {
- for (int cf = 1; cf <= 8; ++cf)
- _menu.disableMenuItem(_menu._discussMenu[cf]);
-
- Common::String sYou = getEngineString(S_YOU);
- Common::String sAre = getEngineString(S_ARE);
- Common::String sAlone = getEngineString(S_ALONE);
-
- clearUpperRightPart();
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sYou) / 2), 30);
- _screenSurface.drawString(sYou, 4);
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAre) / 2), 50);
- _screenSurface.drawString(sAre, 4);
- _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAlone) / 2), 70);
- _screenSurface.drawString(sAlone, 4);
-
- _currBitIndex = 0;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Bureau
- * @remarks Originally called 'cpl10'
- */
-int MortevielleEngine::getPresenceStatsDiningRoom(int &hour) {
- int day, minute;
-
- int retVal = 0;
- updateHour(day, hour, minute);
- if (((hour > 7) && (hour < 11)) || ((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
- retVal = 100;
- else if ((hour == 11) || ((hour > 20) && (hour < 24)))
- retVal = 45;
- else if (((hour > 13) && (hour < 17)) || (hour == 18))
- retVal = 35;
- else if (hour == 17)
- retVal = 60;
- else if ((hour >= 0) && (hour < 8))
- retVal = 5;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Bureau
- * @remarks Originally called 'cpl11'
- */
-int MortevielleEngine::getPresenceStatsBureau(int &hour) {
- int day, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if (((hour > 8) && (hour < 12)) || ((hour > 20) && (hour < 24)))
- retVal = 25;
- else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
- retVal = 5;
- else if ((hour > 13) && (hour < 17))
- retVal = 55;
- else if ((hour > 16) && (hour < 19))
- retVal = 45;
- else if ((hour >= 0) && (hour < 9))
- retVal = 0;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Kitchen
- * @remarks Originally called 'cpl12'
- */
-int MortevielleEngine::getPresenceStatsKitchen() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if (((hour > 8) && (hour < 15)) || ((hour > 16) && (hour < 22)))
- retVal = 55;
- else if (((hour > 14) && (hour < 17)) || ((hour > 21) && (hour < 24)))
- retVal = 25;
- else if ((hour >= 0) && (hour < 5))
- retVal = 0;
- else if ((hour > 4) && (hour < 9))
- retVal = 15;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Attic
- * @remarks Originally called 'cpl13'
- */
-int MortevielleEngine::getPresenceStatsAttic() {
- return 0;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Landing
- * @remarks Originally called 'cpl15'
- */
-int MortevielleEngine::getPresenceStatsLanding() {
- int day, hour, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if ((hour > 7) && (hour < 12))
- retVal = 25;
- else if ((hour > 11) && (hour < 14))
- retVal = 0;
- else if ((hour > 13) && (hour < 18))
- retVal = 10;
- else if ((hour > 17) && (hour < 20))
- retVal = 55;
- else if ((hour > 19) && (hour < 22))
- retVal = 5;
- else if ((hour > 21) && (hour < 24))
- retVal = 15;
- else if ((hour >= 0) && (hour < 8))
- retVal = -15;
-
- return retVal;
-}
-
-/**
- * Engine function - Get Presence Statistics - Room Chapel
- * @remarks Originally called 'cpl20'
- */
-int MortevielleEngine::getPresenceStatsChapel(int &hour) {
- int day, minute;
- int retVal = 0;
-
- updateHour(day, hour, minute);
- if (hour == 10)
- retVal = 65;
- else if ((hour > 10) && (hour < 21))
- retVal = 5;
- else if ((hour > 20) && (hour < 24))
- retVal = -15;
- else if ((hour >= 0) && (hour < 5))
- retVal = -300;
- else if ((hour > 4) && (hour < 10))
- retVal = -5;
-
- return retVal;
-}
-
-/**
- * Engine function - Check who is in the Green Room
- * @remarks Originally called 'quelq1'
- */
-void MortevielleEngine::setPresenceGreenRoom(int roomId) {
- int rand = getRandomNumber(1, 2);
- if (roomId == GREEN_ROOM) {
- if (rand == 1)
- _roomPresenceLuc = true;
- else
- _roomPresenceIda = true;
- } else if (roomId == DARKBLUE_ROOM) {
- if (rand == 1)
- _roomPresenceGuy = true;
- else
- _roomPresenceEva = true;
- }
-
- _currBitIndex = 10;
-}
-
-/**
- * Engine function - Check who is in the Purple Room
- * @remarks Originally called 'quelq2'
- */
-void MortevielleEngine::setPresencePurpleRoom() {
- if (_place == PURPLE_ROOM)
- _purpleRoomPresenceLeo = true;
- else
- _room9PresenceLeo = true;
-
- _currBitIndex = 10;
-}
-
-/**
- * Engine function - Check who is in the Blue Room
- * @remarks Originally called 'quelq5'
- */
-void MortevielleEngine::setPresenceBlueRoom() {
- _roomPresenceMax = true;
- _currBitIndex = 10;
-}
-
-/**
- * Engine function - Check who is in the Red Room
- * @remarks Originally called 'quelq6'
- */
-void MortevielleEngine::setPresenceRedRoom(int roomId) {
- if (roomId == RED_ROOM)
- _roomPresenceBob = true;
- else if (roomId == GREEN_ROOM2)
- _roomPresencePat = true;
-
- _currBitIndex = 10;
-}
-
-/**
- * Engine function - Check who is in the Dining Room
- * @remarks Originally called 'quelq10'
- */
-int MortevielleEngine::setPresenceDiningRoom(int hour) {
- int retVal = 0;
-
- if ((hour >= 0) && (hour < 8))
- retVal = checkLeoMaxRandomPresence();
- else {
- int min = 0, max = 0;
- if ((hour > 7) && (hour < 10)) {
- min = 5;
- max = 7;
- } else if ((hour > 9) && (hour < 12)) {
- min = 1;
- max = 4;
- } else if (((hour > 11) && (hour < 15)) || ((hour > 18) && (hour < 21))) {
- min = 6;
- max = 8;
- } else if (((hour > 14) && (hour < 19)) || ((hour > 20) && (hour < 24))) {
- min = 1;
- max = 5;
- }
- retVal = selectCharacters(min, max);
- }
- showPeoplePresent(retVal);
-
- return retVal;
-}
-
-/**
- * Engine function - Check who is in the Bureau
- * @remarks Originally called 'quelq11'
- */
-int MortevielleEngine::setPresenceBureau(int hour) {
- int retVal = 0;
-
- if ((hour >= 0) && (hour < 8))
- retVal = checkLeoMaxRandomPresence();
- else {
- int min = 0, max = 0;
- if (((hour > 7) && (hour < 10)) || ((hour > 20) && (hour < 24))) {
- min = 1;
- max = 3;
- } else if (((hour > 9) && (hour < 12)) || ((hour > 13) && (hour < 19))) {
- min = 1;
- max = 4;
- } else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21))) {
- min = 1;
- max = 2;
- }
- retVal = selectCharacters(min, max);
- }
- showPeoplePresent(retVal);
-
- return retVal;
-}
-
-/**
- * Engine function - Check who is in the Kitchen
- * @remarks Originally called 'quelq12'
- */
-int MortevielleEngine::setPresenceKitchen() {
- int retVal = checkLeoMaxRandomPresence();
- showPeoplePresent(retVal);
-
- return retVal;
-}
-
-/**
- * Engine function - Check who is in the Landing
- * @remarks Originally called 'quelq15'
- */
-int MortevielleEngine::setPresenceLanding() {
- bool test = false;
- int rand = 0;
- do {
- rand = getRandomNumber(1, 8);
- test = (((rand == 1) && (_purpleRoomPresenceLeo || _room9PresenceLeo)) ||
- ((rand == 2) && _roomPresencePat) ||
- ((rand == 3) && _roomPresenceGuy) ||
- ((rand == 4) && _roomPresenceEva) ||
- ((rand == 5) && _roomPresenceBob) ||
- ((rand == 6) && _roomPresenceLuc) ||
- ((rand == 7) && _roomPresenceIda) ||
- ((rand == 8) && _roomPresenceMax));
- } while (test);
-
- int retVal = convertCharacterIndexToBitIndex(rand);
- showPeoplePresent(retVal);
-
- return retVal;
-}
-
-/**
- * Engine function - Check who is in the chapel
- * @remarks Originally called 'quelq20'
- */
-int MortevielleEngine::setPresenceChapel(int hour) {
- int retVal = 0;
-
- if (((hour >= 0) && (hour < 10)) || ((hour > 18) && (hour < 24)))
- retVal = checkLeoMaxRandomPresence();
- else {
- int min = 0, max = 0;
- if ((hour > 9) && (hour < 12)) {
- min = 3;
- max = 7;
- } else if ((hour > 11) && (hour < 18)) {
- min = 1;
- max = 2;
- } else if (hour == 18) {
- min = 2;
- max = 4;
- }
- retVal = selectCharacters(min, max);
- }
- showPeoplePresent(retVal);
-
- return retVal;
-}
-
-/**
- * Engine function - Get the answer after you known a door
- * @remarks Originally called 'frap'
- */
-void MortevielleEngine::getKnockAnswer() {
- int day, hour, minute;
-
- updateHour(day, hour, minute);
- if ((hour >= 0) && (hour < 8))
- _crep = 190;
- else {
- if (getRandomNumber(1, 100) > 70)
- _crep = 190;
- else
- _crep = 147;
- }
-}
-
-/**
- * Engine function - Get Room Presence Bit Index
- * @remarks Originally called 'nouvp'
- */
-int MortevielleEngine::getPresenceBitIndex(int roomId) {
- int bitIndex = 0;
- if (roomId == GREEN_ROOM) {
- if (_roomPresenceLuc)
- bitIndex = 4; // LUC
- if (_roomPresenceIda)
- bitIndex = 2; // IDA
- } else if ( ((roomId == PURPLE_ROOM) && (_purpleRoomPresenceLeo))
- || ((roomId == ROOM9) && (_room9PresenceLeo)))
- bitIndex = 128; // LEO
- else if (roomId == DARKBLUE_ROOM) {
- if (_roomPresenceGuy)
- bitIndex = 32; // GUY
- if (_roomPresenceEva)
- bitIndex = 16; // EVA
- } else if ((roomId == BLUE_ROOM) && (_roomPresenceMax))
- bitIndex = 1; // MAX
- else if ((roomId == RED_ROOM) && (_roomPresenceBob))
- bitIndex = 8; // BOB
- else if ((roomId == GREEN_ROOM2) && (_roomPresencePat))
- bitIndex = 64; // PAT
- else if ( ((roomId == TOILETS) && (_toiletsPresenceBobMax))
- || ((roomId == BATHROOM) && (_bathRoomPresenceBobMax)) )
- bitIndex = 9; // BOB + MAX
-
- if (bitIndex != 9)
- showPeoplePresent(bitIndex);
-
- return bitIndex;
-}
-
-/**
- * Engine function - initGame
- * @remarks Originally called 'dprog'
- */
-void MortevielleEngine::initGame() {
- _place = MANOR_FRONT;
- _currentHourCount = 0;
- if (!_coreVar._alreadyEnteredManor)
- _blo = true;
- _inGameHourDuration = kTime1;
- _currentDayHour = readclock();
-}
-
-/**
- * Engine function - Set Random Presence - Green Room
- * @remarks Originally called 'pl1'
- */
-void MortevielleEngine::setRandomPresenceGreenRoom(int cf) {
- if ( ((_place == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
- || ((_place == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) ) {
- int p = getPresenceStatsGreenRoom();
- int rand;
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresenceGreenRoom(_place);
- }
-}
-
-/**
- * Engine function - Set Random Presence - Purple Room
- * @remarks Originally called 'pl2'
- */
-void MortevielleEngine::setRandomPresencePurpleRoom(int cf) {
- if (!_purpleRoomPresenceLeo) {
- int p = getPresenceStatsPurpleRoom();
- int rand;
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresencePurpleRoom();
- }
-}
-
-/**
- * Engine function - Set Random Presence - Blue Room
- * @remarks Originally called 'pl5'
- */
-void MortevielleEngine::setRandomPresenceBlueRoom(int cf) {
- if (!_roomPresenceMax) {
- int p = getPresenceStatsBlueRoom();
- int rand;
-
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresenceBlueRoom();
- }
-}
-
-/**
- * Engine function - Set Random Presence - Red Room
- * @remarks Originally called 'pl6'
- */
-void MortevielleEngine::setRandomPresenceRedRoom(int cf) {
- if ( ((_place == RED_ROOM) && (!_roomPresenceBob))
- || ((_place == GREEN_ROOM2) && (!_roomPresencePat)) ) {
- int p = getPresenceStatsRedRoom();
- int rand;
-
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresenceRedRoom(_place);
- }
-}
-
-/**
- * Engine function - Set Random Presence - Room 9
- * @remarks Originally called 'pl9'
- */
-void MortevielleEngine::setRandomPresenceRoom9(int cf) {
- if (!_room9PresenceLeo) {
- cf = -10;
- int p, rand;
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresencePurpleRoom();
- }
-}
-
-/**
- * Engine function - Set Random Presence - Dining Room
- * @remarks Originally called 'pl10'
- */
-void MortevielleEngine::setRandomPresenceDiningRoom(int cf) {
- int h, rand;
- int p = getPresenceStatsDiningRoom(h);
- phaz(rand, p, cf);
-
- if (rand > p)
- displayAloneText();
- else
- setPresenceDiningRoom(h);
-}
-
-/**
- * Engine function - Set Random Presence - Bureau
- * @remarks Originally called 'pl11'
- */
-void MortevielleEngine::setRandomPresenceBureau(int cf) {
- int h, rand;
-
- int p = getPresenceStatsBureau(h);
- phaz(rand, p, cf);
- if (rand > p)
- displayAloneText();
- else
- setPresenceBureau(h);
-}
-
-/**
- * Engine function - Set Random Presence - Kitchen
- * @remarks Originally called 'pl12'
- */
-void MortevielleEngine::setRandomPresenceKitchen(int cf) {
- int p, rand;
-
- p = getPresenceStatsKitchen();
- phaz(rand, p, cf);
- if (rand > p)
- displayAloneText();
- else
- setPresenceKitchen();
-}
-
-/**
- * Engine function - Set Random Presence - Attic / Cellar
- * @remarks Originally called 'pl13'
- */
-void MortevielleEngine::setRandomPresenceAttic(int cf) {
- int p, rand;
-
- p = getPresenceStatsAttic();
- phaz(rand, p, cf);
- if (rand > p)
- displayAloneText();
- else
- setPresenceKitchen();
-}
-
-/**
- * Engine function - Set Random Presence - Landing
- * @remarks Originally called 'pl15'
- */
-void MortevielleEngine::setRandomPresenceLanding(int cf) {
- int p, rand;
-
- p = getPresenceStatsLanding();
- phaz(rand, p, cf);
- if (rand > p)
- displayAloneText();
- else
- setPresenceLanding();
-}
-
-/**
- * Engine function - Set Random Presence - Chapel
- * @remarks Originally called 'pl20'
- */
-void MortevielleEngine::setRandomPresenceChapel(int cf) {
- int h, rand;
-
- int p = getPresenceStatsChapel(h);
- phaz(rand, p, cf);
- if (rand > p)
- displayAloneText();
- else
- setPresenceChapel(h);
-}
-
-/**
- * Start music or speech
- * @remarks Originally called 'musique'
- */
-void MortevielleEngine::startMusicOrSpeech(int so) {
- if (so == 0) {
- /* musik(0) */
- ;
- } else if ((!_introSpeechPlayed) && (!_coreVar._alreadyEnteredManor)) {
- // Type 1: Speech
- _speechManager.startSpeech(10, 1, 1);
- _introSpeechPlayed = true;
- } else {
- if (((_coreVar._currPlace == MOUNTAIN) || (_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) && (getRandomNumber(1, 3) == 2))
- // Type 1: Speech
- _speechManager.startSpeech(9, getRandomNumber(2, 4), 1);
- else if ((_coreVar._currPlace == CHAPEL) && (getRandomNumber(1, 2) == 1))
- // Type 1: Speech
- _speechManager.startSpeech(8, 1, 1);
- else if ((_coreVar._currPlace == WELL) && (getRandomNumber(1, 2) == 2))
- // Type 1: Speech
- _speechManager.startSpeech(12, 1, 1);
- else if (_coreVar._currPlace == INSIDE_WELL)
- // Type 1: Speech
- _speechManager.startSpeech(13, 1, 1);
- else
- // Type 2 : music
- _speechManager.startSpeech(getRandomNumber(1, 17), 1, 2);
- }
-}
-
-/**
- * Engine function - You lose!
- * @remarks Originally called 'tperd'
- */
-void MortevielleEngine::loseGame() {
- resetOpenObjects();
- _roomDoorId = OWN_ROOM;
- _mchai = 0;
- _menu.unsetSearchMenu();
- if (!_blo)
- getPresence(MANOR_FRONT);
-
- _loseGame = true;
- clearUpperLeftPart();
- _screenSurface.drawBox(60, 35, 400, 50, 15);
- handleDescriptionText(9, _crep);
- clearDescriptionBar();
- clearVerbBar();
- _col = false;
- _syn = false;
- _destinationOk = false;
-}
-
-/**
- * Engine function - Check inventory for a given object
- * @remarks Originally called 'cherjer'
- */
-bool MortevielleEngine::checkInventory(int objectId) {
- bool retVal = false;
- for (int i = 1; i <= 6; ++i)
- retVal = (retVal || (_coreVar._inventory[i] == objectId));
-
- if (_coreVar._selectedObjectId == objectId)
- retVal = true;
-
- return retVal;
-}
-
-/**
- * Engine function - Display Dining Room
- * @remarks Originally called 'st1sama'
- */
-void MortevielleEngine::displayDiningRoom() {
- _coreVar._currPlace = DINING_ROOM;
- affrep();
-}
-
-/**
- * Engine function - Start non interactive Dialog
- * @remarks Originally called 'sparl'
- */
-void MortevielleEngine::startDialog(int16 rep) {
- const int haut[9] = { 0, 0, 1, -3, 6, -2, 2, 7, -1 };
- int key;
-
- assert(rep >= 0);
-
- _mouse.hideMouse();
- Common::String dialogStr = getString(rep + kDialogStringIndex);
- _text.displayStr(dialogStr, 230, 4, 65, 24, 5);
- _dialogManager.drawF3F8();
-
- key = 0;
- do {
- _speechManager.startSpeech(rep, haut[_caff - 69], 0);
- key = _dialogManager.waitForF3F8();
- if (shouldQuit())
- return;
- } while (key != 66);
- hirs();
- _mouse.showMouse();
-}
-
-/**
- * Engine function - End of Search: reset globals
- * @remarks Originally called 'finfouill'
- */
-void MortevielleEngine::endSearch() {
- _heroSearching = false;
- _obpart = false;
- _searchCount = 0;
- _menu.unsetSearchMenu();
-}
-
-/**
- * Engine function - Go to Dining room
- * @remarks Originally called 't1sama'
- */
-void MortevielleEngine::gotoDiningRoom() {
- int day, hour, minute;
-
- updateHour(day, hour, minute);
- if ((hour < 5) && (_coreVar._currPlace > ROOM18)) {
- if (!checkInventory(137)) { //You don't have the keys, and it's late
- _crep = 1511;
- loseGame();
- } else
- displayDiningRoom();
- } else if (!_coreVar._alreadyEnteredManor) { //Is it your first time?
- _currBitIndex = 255; // Everybody is present
- showPeoplePresent(_currBitIndex);
- _caff = 77;
- drawPictureWithText();
- _screenSurface.drawBox(223, 47, 155, 91, 15);
- handleDescriptionText(2, 33);
- testKey(false);
- mennor();
- _mouse.hideMouse();
- hirs();
- premtet();
- startDialog(140);
- drawRightFrame();
- drawClock();
- _mouse.showMouse();
- _coreVar._currPlace = OWN_ROOM;
- affrep();
- resetPresenceInRooms(DINING_ROOM);
- if (!_blo)
- getPresence(OWN_ROOM);
- _currBitIndex = 0;
- _savedBitIndex = 0;
- _coreVar._alreadyEnteredManor = true;
- } else
- displayDiningRoom();
-}
-
-/**
- * Engine function - Check Manor distance (in the mountains)
- * @remarks Originally called 't1neig'
- */
-void MortevielleEngine::checkManorDistance() {
- ++_manorDistance;
- if (_manorDistance > 2) {
- _crep = 1506;
- loseGame();
- } else {
- _destinationOk = true;
- _coreVar._currPlace = MOUNTAIN;
- affrep();
- }
-}
-
-/**
- * Engine function - Go to Manor front
- * @remarks Originally called 't1deva'
- */
-void MortevielleEngine::gotoManorFront() {
- _manorDistance = 0;
- _coreVar._currPlace = MANOR_FRONT;
- affrep();
-}
-
-/**
- * Engine function - Go to Manor back
- * @remarks Originally called 't1derr'
- */
-void MortevielleEngine::gotoManorBack() {
- _coreVar._currPlace = MANOR_BACK;
- affrep();
-}
-
-/**
- * Engine function - Dead : Flooded in Well
- * @remarks Originally called 't1deau'
- */
-void MortevielleEngine::floodedInWell() {
- _crep = 1503;
- loseGame();
-}
-
-/**
- * Engine function - Change Graphical Device
- * @remarks Originally called 'change_gd'
- */
-void MortevielleEngine::changeGraphicalDevice(int newDevice) {
- _mouse.hideMouse();
- _currGraphicalDevice = newDevice;
- hirs();
- _mouse.initMouse();
- _mouse.showMouse();
- drawRightFrame();
- prepareRoom();
- drawClock();
- if (_currBitIndex != 0)
- showPeoplePresent(_currBitIndex);
- else
- displayAloneText();
- clearDescriptionBar();
- clearVerbBar();
- _maff = 68;
- drawPictureWithText();
- handleDescriptionText(2, _crep);
- _menu.displayMenu();
-}
-
-/**
- * Called when a savegame has been loaded.
- * @remarks Originally called 'antegame'
- */
-void MortevielleEngine::gameLoaded() {
- _mouse.hideMouse();
- _menu._menuDisplayed = false;
- _loseGame = true;
- _anyone = false;
- _destinationOk = true;
- _col = false;
- _hiddenHero = false;
- _uptodatePresence = false;
- _maff = 68;
- _menuOpcode = OPCODE_NONE;
- _introSpeechPlayed = false;
- _x = 0;
- _y = 0;
- _num = 0;
- _startHour = 0;
- _endHour = 0;
- _searchCount = 0;
- _roomDoorId = OWN_ROOM;
- _syn = true;
- _heroSearching = true;
- _mchai = 0;
- _manorDistance = 0;
- resetOpenObjects();
- _takeObjCount = 0;
- affrep();
- _hintPctMessage = getString(580);
-
- _destinationOk = false;
- _endGame = true;
- _loseGame = false;
- _heroSearching = false;
-
- displayAloneText();
- prepareRoom();
- drawClock();
- drawPictureWithText();
- handleDescriptionText(2, _crep);
- clearVerbBar();
- _endGame = false;
- _menu.setDestinationText(_coreVar._currPlace);
- _menu.setInventoryText();
- if (_coreVar._selectedObjectId != 0)
- displayItemInHand(_coreVar._selectedObjectId + 400);
- _mouse.showMouse();
-}
-
-/**
- * Engine function - Handle OpCodes
- * @remarks Originally called 'tsitu'
- */
-void MortevielleEngine::handleOpcode() {
- if (!_col)
- clearDescriptionBar();
- _syn = false;
- _keyPressedEsc = false;
- if (!_anyone) {
- if (_uptodatePresence) {
- if ((_msg[3] == MENU_MOVE) || (_msg[4] == OPCODE_LEAVE) || (_msg[4] == OPCODE_SLEEP) || (_msg[4] == OPCODE_EAT)) {
- _controlMenu = 4;
- mennor();
- return;
- }
- }
- if (_msg[3] == MENU_MOVE)
- fctMove();
- if (_msg[3] == MENU_DISCUSS)
- fctDiscuss();
- if (_msg[3] == MENU_INVENTORY)
- fctInventoryTake();
- if (_msg[4] == OPCODE_ATTACH)
- fctAttach();
- if (_msg[4] == OPCODE_WAIT)
- fctWait();
- if (_msg[4] == OPCODE_FORCE)
- fctForce();
- if (_msg[4] == OPCODE_SLEEP)
- fctSleep();
- if (_msg[4] == OPCODE_LISTEN)
- fctListen();
- if (_msg[4] == OPCODE_ENTER)
- fctEnter();
- if (_msg[4] == OPCODE_CLOSE)
- fctClose();
- if (_msg[4] == OPCODE_SEARCH)
- fctSearch();
- if (_msg[4] == OPCODE_KNOCK)
- fctKnock();
- if (_msg[4] == OPCODE_SCRATCH)
- fctScratch();
- if (_msg[4] == OPCODE_READ)
- fctRead();
- if (_msg[4] == OPCODE_EAT)
- fctEat();
- if (_msg[4] == OPCODE_PLACE)
- fctPlace();
- if (_msg[4] == OPCODE_OPEN)
- fctOpen();
- if (_msg[4] == OPCODE_TAKE)
- fctTake();
- if (_msg[4] == OPCODE_LOOK)
- fctLook();
- if (_msg[4] == OPCODE_SMELL)
- fctSmell();
- if (_msg[4] == OPCODE_SOUND)
- fctSound();
- if (_msg[4] == OPCODE_LEAVE)
- fctLeave();
- if (_msg[4] == OPCODE_LIFT)
- fctLift();
- if (_msg[4] == OPCODE_TURN)
- fctTurn();
- if (_msg[4] == OPCODE_SSEARCH)
- fctSelfSearch();
- if (_msg[4] == OPCODE_SREAD)
- fctSelfRead();
- if (_msg[4] == OPCODE_SPUT)
- fctSelfPut();
- if (_msg[4] == OPCODE_SLOOK)
- fctSelftLook();
- _hiddenHero = false;
-
- if (_msg[4] == OPCODE_SHIDE)
- fctSelfHide();
- } else {
- if (_anyone) {
- interactNPC();
- _anyone = false;
- mennor();
- return;
- }
- }
- int hour, day, minute;
- updateHour(day, hour, minute);
- if ((((hour == 12) || (hour == 13) || (hour == 19)) && (_coreVar._currPlace != DINING_ROOM)) ||
- ((hour > 0) && (hour < 6) && (_coreVar._currPlace != OWN_ROOM)))
- ++_coreVar._faithScore;
- if (((_coreVar._currPlace < CRYPT) || (_coreVar._currPlace > MOUNTAIN)) && (_coreVar._currPlace != INSIDE_WELL)
- && (_coreVar._currPlace != OWN_ROOM) && (_coreVar._selectedObjectId != 152) && (!_loseGame)) {
- if ((_coreVar._faithScore > 99) && (hour > 8) && (hour < 16)) {
- _crep = 1501;
- loseGame();
- }
- if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
- _crep = 1508;
- loseGame();
- }
- if ((day > 1) && (hour > 8) && (!_loseGame)) {
- _crep = 1502;
- loseGame();
- }
- }
- mennor();
-}
-
-/**
- * Engine function - Transform time into a char
- * @remarks Originally called 'tmaj3'
- */
-void MortevielleEngine::hourToChar() {
- int day, hour, minute;
-
- updateHour(day, hour, minute);
- if (minute == 30)
- minute = 1;
- hour += day * 24;
- minute += hour * 2;
- _coreVar._fullHour = chr(minute);
-}
-
-/**
- * Engine function - extract time from a char
- * @remarks Originally called 'theure'
- */
-void MortevielleEngine::charToHour() {
- int fullHour = ord(_coreVar._fullHour);
- int tmpHour = fullHour % 48;
- _currDay = fullHour / 48;
- _currHalfHour = tmpHour % 2;
- _currHour = tmpHour / 2;
- _hour = _currHour;
- if (_currHalfHour == 1)
- _minute = 30;
- else
- _minute = 0;
-}
-
-/**
- * Engine function - Clear upper left part of Screen - Type 1
- * @remarks Originally called 'clsf1'
- */
-void MortevielleEngine::clearUpperLeftPart() {
- _mouse.hideMouse();
- _screenSurface.fillRect(0, Common::Rect(0, 11, 514, 175));
- _mouse.showMouse();
-}
-
-/**
- * Engine function - Clear low bar used by description
- * @remarks Originally called 'clsf2'
- */
-void MortevielleEngine::clearDescriptionBar() {
- _mouse.hideMouse();
- if (_largestClearScreen) {
- _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 199));
- _screenSurface.drawBox(0, 175, 634, 24, 15);
- _largestClearScreen = false;
- } else {
- _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 190));
- _screenSurface.drawBox(0, 175, 634, 15, 15);
- }
- _mouse.showMouse();
-}
-
-/**
- * Engine function - Clear lowest bar used by verbs
- * @remarks Originally called 'clsf3'
- */
-void MortevielleEngine::clearVerbBar() {
- _mouse.hideMouse();
- _screenSurface.fillRect(0, Common::Rect(1, 192, 633, 199));
- _screenSurface.drawBox(0, 191, 634, 8, 15);
- _mouse.showMouse();
-}
-
-/**
- * Engine function - Clear upper right part of the screen
- * @remarks Originally called 'clsf10'
- */
-void MortevielleEngine::clearUpperRightPart() {
- int x1, x2;
- Common::String st;
-
- _mouse.hideMouse();
- if (_resolutionScaler == 1) {
- x2 = 634;
- x1 = 534;
- } else {
- x2 = 600;
- x1 = 544;
- }
- // Clear ambiance description
- _screenSurface.fillRect(15, Common::Rect(x1, 93, x2, 98));
- if (_coreVar._faithScore < 33)
- st = getEngineString(S_COOL);
- else if (_coreVar._faithScore < 66)
- st = getEngineString(S_LOURDE);
- else if (_coreVar._faithScore > 65)
- st = getEngineString(S_MALSAINE);
-
- x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
- _screenSurface.putxy(x1, 92);
- _screenSurface.drawString(st, 4);
-
- // Clear person list
- _screenSurface.fillRect(15, Common::Rect(560, 24, 610, 86));
- _mouse.showMouse();
-}
-
-/**
- * Engine function - Get a random number between two values
- * @remarks Originally called 'get_random_number' and 'hazard'
- */
-int MortevielleEngine::getRandomNumber(int minval, int maxval) {
- return _randomSource.getRandomNumber(maxval - minval) + minval;
-}
-
-/**
- * Engine function - Show alert "use move menu"
- * @remarks Originally called 'aldepl'
- */
-void MortevielleEngine::showMoveMenuAlert() {
- _dialogManager.show(getEngineString(S_USE_DEP_MENU), 1);
-}
-
-/**
- * The original engine used this method to display a starting text screen letting the player
- * select the graphics mode to use
- * @remarks Originally called 'dialpre'
- */
-void MortevielleEngine::showConfigScreen() {
- _crep = 998;
-}
-
-/**
- * Decodes a number of 64 byte blocks
- * @param pStart Start of data
- * @param count Number of 64 byte blocks
- * @remarks Originally called 'zzuul'
- */
-void MortevielleEngine::decodeNumber(byte *pStart, int count) {
- while (count-- > 0) {
- for (int idx = 0; idx < 64; ++pStart, ++idx) {
- uint16 v = ((*pStart - 0x80) << 1) + 0x80;
-
- if (v & 0x8000)
- *pStart = 0;
- else if (v & 0xff00)
- *pStart = 0xff;
- else
- *pStart = (byte)v;
- }
- }
-}
-
-void MortevielleEngine::cinq_huit(char &c, int &idx, byte &pt, bool &the_end) {
- uint16 oct, ocd;
-
- /* 5-8 */
- oct = _inpBuffer[idx];
- oct = ((uint16)(oct << (16 - pt))) >> (16 - pt);
- if (pt < 6) {
- ++idx;
- oct = oct << (5 - pt);
- pt += 11;
- oct = oct | ((uint)_inpBuffer[idx] >> pt);
- } else {
- pt -= 5;
- oct = (uint)oct >> pt;
- }
-
- switch (oct) {
- case 11:
- c = '$';
- the_end = true;
- break;
- case 30:
- case 31:
- ocd = _inpBuffer[idx];
- ocd = (uint16)(ocd << (16 - pt)) >> (16 - pt);
- if (pt < 6) {
- ++idx;
- ocd = ocd << (5 - pt);
- pt += 11;
- ocd = ocd | ((uint)_inpBuffer[idx] >> pt);
- } else {
- pt -= 5;
- ocd = (uint)ocd >> pt;
- }
-
- if (oct == 30)
- c = chr(tab30[ocd]);
- else
- c = chr(tab31[ocd]);
-
- if (c == '\0') {
- the_end = true;
- c = '#';
- }
- break;
- default:
- c = chr(tabdr[oct]);
- break;
- }
-}
-
-/**
- * Decode and extract the line with the given Id
- * @remarks Originally called 'deline'
- */
-Common::String MortevielleEngine::getString(int num) {
- Common::String wrkStr = "";
-
- if (num < 0) {
- warning("getString(%d): num < 0! Skipping", num);
- } else if (!_txxFileFl) {
- wrkStr = getGameString(num);
- } else {
- int hint = _ntpBuffer[num]._hintId;
- byte point = _ntpBuffer[num]._point;
- int length = 0;
- bool endFl = false;
- char let;
- do {
- cinq_huit(let, hint, point, endFl);
- wrkStr += let;
- ++length;
- } while (!endFl);
- }
-
- while (wrkStr.lastChar() == '$')
- // Remove trailing '$'s
- wrkStr.deleteLastChar();
-
- return wrkStr;
-}
-
-void MortevielleEngine::copcha() {
- for (int i = kAcha; i < kAcha + 390; i++)
- _tabdon[i] = _tabdon[i + 390];
-}
-
-/**
- * Engine function - When restarting the game, reset the main variables used by the engine
- * @remarks Originally called 'inzon'
- */
-void MortevielleEngine::resetVariables() {
- copcha();
-
- _coreVar._alreadyEnteredManor = false;
- _coreVar._selectedObjectId = 0;
- _coreVar._cellarObjectId = 0;
- _coreVar._atticBallHoleObjectId = 0;
- _coreVar._atticRodHoleObjectId = 0;
- _coreVar._wellObjectId = 0;
- _coreVar._secretPassageObjectId = 0;
- _coreVar._purpleRoomObjectId = 136;
- _coreVar._cryptObjectId = 141;
- _coreVar._faithScore = getRandomNumber(4, 10);
- _coreVar._currPlace = MANOR_FRONT;
-
- for (int i = 2; i <= 6; ++i)
- _coreVar._inventory[i] = 0;
-
- // Only object in inventory: a gun
- _coreVar._inventory[1] = 113;
-
- _coreVar._fullHour = chr(20);
-
- for (int i = 1; i <= 10; ++i)
- _coreVar._pctHintFound[i] = ' ';
-
- for (int i = 1; i <= 6; ++i)
- _coreVar._availableQuestion[i] = '*';
-
- for (int i = 7; i <= 9; ++i)
- _coreVar._availableQuestion[i] = ' ';
-
- for (int i = 10; i <= 28; ++i)
- _coreVar._availableQuestion[i] = '*';
-
- for (int i = 29; i <= 42; ++i)
- _coreVar._availableQuestion[i] = ' ';
-
- _coreVar._availableQuestion[33] = '*';
-
- for (int i = 1; i <= 8; ++i)
- _nbrep[i] = 0;
-
- init_nbrepm();
-}
-
-/**
- * Engine function - Set the palette
- * @remarks Originally called 'writepal'
- */
-void MortevielleEngine::setPal(int n) {
- switch (_currGraphicalDevice) {
- case MODE_TANDY:
- case MODE_EGA:
- case MODE_AMSTRAD1512:
- for (int i = 1; i <= 16; ++i) {
- _mem[(0x7000 * 16) + (2 * i)] = _stdPal[n][i].x;
- _mem[(0x7000 * 16) + (2 * i) + 1] = _stdPal[n][i].y;
- }
- break;
- case MODE_CGA: {
- nhom pal[16];
- for (int i = 0; i < 16; ++i) {
- pal[i] = _cgaPal[n]._a[i];
- }
-
- if (n < 89)
- palette(_cgaPal[n]._p);
-
- for (int i = 0; i <= 15; ++i)
- displayCGAPattern(i, _patternArr[pal[i]._id], pal);
- }
- break;
- default:
- break;
- }
-}
-
-/**
- * Engine function - Display a CGA pattern, using a specified palette
- * @remarks Originally called 'outbloc'
- */
-void MortevielleEngine::displayCGAPattern(int n, Pattern p, nhom *pal) {
- int addr = n * 404 + 0xd700;
-
- WRITE_LE_UINT16(&_mem[0x6000 * 16 + addr], p._tax);
- WRITE_LE_UINT16(&_mem[0x6000 * 16 + addr + 2], p._tay);
- addr += 4;
- for (int i = 0; i < p._tax; ++i) {
- for (int j = 0; j < p._tay; ++j)
- _mem[(0x6000 * 16) + addr + j * p._tax + i] = pal[n]._hom[p._des[i + 1][j + 1]];
- }
-}
-
-/**
- * Engine function - Load Palette from File
- * @remarks Originally called 'charpal'
- */
-void MortevielleEngine::loadPalette() {
- Common::File f;
- byte b;
-
- if (!f.open("fxx.mor")) {
- if (f.open("mfxx.mor"))
- f.seek(7 * 25);
- else
- error("Missing file - fxx.mor");
- }
-
- for (int i = 0; i < 108; ++i)
- _fxxBuffer[i] = f.readSint16LE();
- f.close();
-
- if (!f.open("plxx.mor"))
- error("Missing file - plxx.mor");
- for (int i = 0; i <= 90; ++i) {
- for (int j = 1; j <= 16; ++j) {
- _stdPal[i][j].x = f.readByte();
- _stdPal[i][j].y = f.readByte();
- }
- }
- f.close();
-
- if (!f.open("cxx.mor"))
- error("Missing file - cxx.mor");
-
- for (int j = 0; j <= 90; ++j) {
- _cgaPal[j]._p = f.readByte();
- for (int i = 0; i <= 15; ++i) {
- nhom &with = _cgaPal[j]._a[i];
-
- b = f.readByte();
- with._id = (uint)b >> 4;
- with._hom[0] = ((uint)b >> 2) & 3;
- with._hom[1] = b & 3;
- }
- }
-
- _cgaPal[10]._a[9] = _cgaPal[10]._a[5];
- for (int j = 0; j <= 14; ++j) {
- _patternArr[j]._tax = f.readByte();
- _patternArr[j]._tay = f.readByte();
- for (int i = 1; i <= 20; ++i) {
- for (int k = 1; k <= 20; ++k)
- _patternArr[j]._des[i][k] = f.readByte();
- }
- }
- f.close();
-}
-
-/**
- * Engine function - Load Texts from File
- * @remarks Originally called 'chartex'
- */
-void MortevielleEngine::loadTexts() {
- Common::File inpFile;
- Common::File ntpFile;
-
- _txxFileFl = false;
- if (getLanguage() == Common::EN_ANY) {
- warning("English version expected - Switching to DAT file");
- return;
- }
-
- if (!inpFile.open("TXX.INP")) {
- if (!inpFile.open("TXX.MOR")) {
- warning("Missing file - TXX.INP or .MOR - Switching to DAT file");
- return;
- }
- }
- if (!ntpFile.open("TXX.NTP")) {
- warning("Missing file - TXX.INP or .MOR - Switching to DAT file");
- return;
- }
-
- if ((inpFile.size() > (kMaxTi * 2)) || (ntpFile.size() > (kMaxTd * 3))) {
- warning("TXX file - Unexpected format - Switching to DAT file");
- return;
- }
-
- for (int i = 0; i < inpFile.size() / 2; ++i)
- _inpBuffer[i] = inpFile.readUint16LE();
-
- inpFile.close();
- _txxFileFl = true;
-
- for (int i = 0; i < (ntpFile.size() / 3); ++i) {
- _ntpBuffer[i]._hintId = ntpFile.readSint16LE();
- _ntpBuffer[i]._point = ntpFile.readByte();
- }
-
- ntpFile.close();
-
-}
-
-void MortevielleEngine::loadBRUIT5() {
- Common::File f;
-
- if (!f.open("bruit5"))
- error("Missing file - bruit5");
-
- f.read(&_mem[kAdrNoise5 * 16 + 0], 149 * 128);
- f.close();
-}
-
-void MortevielleEngine::loadCFIEC() {
- Common::File f;
-
- if (!f.open("cfiec.mor")) {
- if (!f.open("alcfiec.mor"))
- error("Missing file - *cfiec.mor");
- }
-
- _cfiecBufferSize = ((f.size() / 128) + 1) * 128;
- int32 fileSize = f.size();
-
- if (!_reloadCFIEC)
- _cfiecBuffer = (byte *)malloc(sizeof(byte) * _cfiecBufferSize);
-
- for (int32 i = 0; i < fileSize; ++i)
- _cfiecBuffer[i] = f.readByte();
-
- for (int i = fileSize; i < _cfiecBufferSize; i++)
- _cfiecBuffer[i] = 0;
-
- f.close();
-
- _reloadCFIEC = false;
-}
-
-
-void MortevielleEngine::loadCFIPH() {
- Common::File f;
-
- if (!f.open("cfiph.mor")) {
- if (!f.open("alcfiph.mor"))
- error("Missing file - *cfiph.mor");
- }
-
- _speechManager._cfiphBuffer = (int16 *)malloc(sizeof(int16) * (f.size() / 2));
-
- for (int i = 0; i < (f.size() / 2); ++i)
- _speechManager._cfiphBuffer[i] = f.readSint16LE();
-
- f.close();
-}
-
-/**
- * Engine function - Play Music
- * @remarks Originally called 'music'
- */
-void MortevielleEngine::music() {
- if (_soundOff)
- return;
-
- _reloadCFIEC = true;
-
- Common::File fic;
- if (!fic.open("mort.img"))
- error("Missing file - mort.img");
-
- fic.read(&_mem[0x3800 * 16 + 0], 500);
- fic.read(&_mem[0x47a0 * 16 + 0], 123);
- fic.close();
-
- _soundManager.decodeMusic(&_mem[0x3800 * 16], &_mem[0x5000 * 16], 623);
- _addFix = (float)((kTempoMusic - 8)) / 256;
- _speechManager.cctable(_speechManager._tbi);
-
- bool fin = false;
- int k = 0;
- do {
- fin = keyPressed();
- _soundManager.musyc(_speechManager._tbi, 9958, kTempoMusic);
- ++k;
- fin = fin | keyPressed() | (k >= 5);
- } while (!fin);
- while (keyPressed())
- getChar();
-}
-
-/**
- * Engine function - Show title screen
- * @remarks Originally called 'suite'
- */
-void MortevielleEngine::showTitleScreen() {
- hirs();
- handleDescriptionText(7, 2035);
- _caff = 51;
- _text.taffich();
- testKeyboard();
- if (_newGraphicalDevice != _currGraphicalDevice)
- _currGraphicalDevice = _newGraphicalDevice;
- hirs();
- draw(kAdrDes, 0, 0);
-
- Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
- _screenSurface.putxy(104 + 72 * _resolutionScaler, 185);
- _screenSurface.drawString(cpr, 0);
-}
-
-/**
- * Draw picture
- * @remarks Originally called 'dessine'
- */
-void MortevielleEngine::draw(int ad, int x, int y) {
- _mouse.hideMouse();
- setPal(_numpal);
- pictout(ad, 0, x, y);
- _mouse.showMouse();
-}
-
-/**
- * Draw right frame
- * @remarks Originally called 'dessine_rouleau'
- */
-void MortevielleEngine::drawRightFrame() {
- setPal(89);
- if (_currGraphicalDevice == MODE_HERCULES) {
- _mem[0x7000 * 16 + 14] = 15;
- }
- _mouse.hideMouse();
- pictout(0x73a2, 0, 0, 0);
- _mouse.showMouse();
-}
-
-/**
- * Read the current system time
- */
-int MortevielleEngine::readclock() {
- TimeDate dateTime;
- g_system->getTimeAndDate(dateTime);
-
- int m = dateTime.tm_min * 60;
- int h = dateTime.tm_hour * 3600;
- return h + m + dateTime.tm_sec;
-}
-
-/**
- * Engine function - Prepare room and hint string
- * @remarks Originally called 'tinke'
- */
-void MortevielleEngine::prepareRoom() {
- int day, hour, minute;
-
- _anyone = false;
- updateHour(day, hour, minute);
- if (day != _day) {
- _day = day;
- int i = 0;
- do {
- ++i;
- if (_nbrepm[i] != 0)
- --_nbrepm[i];
- _nbrep[i] = 0;
- } while (i != 8);
- }
- if ((hour > _hour) || ((hour == 0) && (_hour == 23))) {
- _hour = hour;
- _minute = 0;
- drawClock();
- int hintCount = 0;
- for (int i = 1; i <= 10; ++i) {
- if (_coreVar._pctHintFound[i] == '*')
- ++hintCount;
- }
-
- Common::String pctStr;
- if (hintCount == 10)
- pctStr = "10";
- else
- pctStr = chr(hintCount + 48);
-
- _hintPctMessage = "[1][";
- _hintPctMessage += getEngineString(S_SHOULD_HAVE_NOTICED);
- _hintPctMessage += pctStr;
- _hintPctMessage += '0';
- _hintPctMessage += getEngineString(S_NUMBER_OF_HINTS);
- _hintPctMessage += "][";
- _hintPctMessage += getEngineString(S_OK);
- _hintPctMessage += ']';
- }
- if (minute > _minute) {
- _minute = 30;
- drawClock();
- }
- if (_mouse._pos.y < 12)
- return;
-
- if (!_blo) {
- if ((hour == 12) || ((hour > 18) && (hour < 21)) || ((hour >= 0) && (hour < 7)))
- _inGameHourDuration = kTime2;
- else
- _inGameHourDuration = kTime1;
- if ((_coreVar._faithScore > 33) && (_coreVar._faithScore < 66))
- _inGameHourDuration -= (_inGameHourDuration / 3);
-
- if (_coreVar._faithScore > 65)
- _inGameHourDuration -= ((_inGameHourDuration / 3) * 2);
-
- int newHour = readclock();
- if ((newHour - _currentDayHour) > _inGameHourDuration) {
- bool activeMenu = _menu._menuActive;
- _menu.eraseMenu();
- _currentHourCount += ((newHour - _currentDayHour) / _inGameHourDuration);
- _currentDayHour = newHour;
- switch (_place) {
- case GREEN_ROOM:
- case DARKBLUE_ROOM:
- setRandomPresenceGreenRoom(_coreVar._faithScore);
- break;
- case PURPLE_ROOM:
- setRandomPresencePurpleRoom(_coreVar._faithScore);
- break;
- case BLUE_ROOM:
- setRandomPresenceBlueRoom(_coreVar._faithScore);
- break;
- case RED_ROOM:
- case GREEN_ROOM2:
- setRandomPresenceRedRoom(_coreVar._faithScore);
- break;
- case ROOM9:
- setRandomPresenceRoom9(_coreVar._faithScore);
- break;
- case DINING_ROOM:
- setRandomPresenceDiningRoom(_coreVar._faithScore);
- break;
- case BUREAU:
- setRandomPresenceBureau(_coreVar._faithScore);
- break;
- case KITCHEN:
- setRandomPresenceKitchen(_coreVar._faithScore);
- break;
- case ATTIC:
- case CELLAR:
- setRandomPresenceAttic(_coreVar._faithScore);
- break;
- case LANDING:
- case ROOM26:
- setRandomPresenceLanding(_coreVar._faithScore);
- break;
- case CHAPEL:
- setRandomPresenceChapel(_coreVar._faithScore);
- break;
- }
- if ((_savedBitIndex != 0) && (_currBitIndex != 10))
- _savedBitIndex = _currBitIndex;
-
- if ((_savedBitIndex == 0) && (_currBitIndex > 0)) {
- if ((_coreVar._currPlace == ATTIC) || (_coreVar._currPlace == CELLAR)) {
- initCaveOrCellar();
- } else if (_currBitIndex == 10) {
- _currBitIndex = 0;
- if (!_uptodatePresence) {
- _uptodatePresence = true;
- _startHour = readclock();
- if (getRandomNumber(1, 5) < 5) {
- clearVerbBar();
- prepareScreenType2();
- displayTextInVerbBar(getEngineString(S_HEAR_NOISE));
- int rand = (getRandomNumber(0, 4)) - 2;
- _speechManager.startSpeech(1, rand, 1);
- clearVerbBar();
- }
- }
- }
- }
-
- if (activeMenu)
- _menu.drawMenu();
- }
- }
- _endHour = readclock();
- if ((_uptodatePresence) && ((_endHour - _startHour) > 17)) {
- getPresenceBitIndex(_place);
- _uptodatePresence = false;
- _startHour = 0;
- if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
- _anyone = true;
- }
-}
-
-/**
- * Engine function - Draw Clock
- * @remarks Originally called 'pendule'
- */
-void MortevielleEngine::drawClock() {
- const int cv[2][12] = {
- { 5, 8, 10, 8, 5, 0, -5, -8, -10, -8, -5, 0 },
- { -5, -3, 0, 3, 5, 6, 5, 3, 0, -3, -5, -6 }
- };
- const int x = 580;
- const int y = 123;
- const int rg = 9;
- int hourColor;
-
- _mouse.hideMouse();
-
- _screenSurface.drawRectangle(570, 118, 20, 10);
- _screenSurface.drawRectangle(578, 114, 6, 18);
- if ((_currGraphicalDevice == MODE_CGA) || (_currGraphicalDevice == MODE_HERCULES))
- hourColor = 0;
- else
- hourColor = 1;
-
- if (_minute == 0)
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y - rg), hourColor);
- else
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y + rg), hourColor);
-
- int hour12 = _hour;
- if (hour12 > 12)
- hour12 -= 12;
- if (hour12 == 0)
- hour12 = 12;
-
- _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * _resolutionScaler, y + cv[1][hour12 - 1], hourColor);
- _mouse.showMouse();
- _screenSurface.putxy(568, 154);
-
- if (_hour > 11)
- _screenSurface.drawString("PM ", 1);
- else
- _screenSurface.drawString("AM ", 1);
-
- _screenSurface.putxy(550, 160);
- if ((_day >= 0) && (_day <= 8)) {
- Common::String tmp = getEngineString(S_DAY);
- tmp.insertChar((char)(_day + 49), 0);
- _screenSurface.drawString(tmp, 1);
- }
-}
-
-void MortevielleEngine::palette(int v1) {
- warning("TODO: palette");
-}
-
-/**
- * Returns a substring of the given string
- * @param s Source string
- * @param idx Starting index (1 based)
- * @param size Number of characters to return
- */
-
-Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t size) {
- // Copy the substring into a temporary buffer
- char *tmp = new char[size + 1];
- strncpy(tmp, s.c_str() + idx - 1, size);
- tmp[size] = '\0';
-
- Common::String result(tmp);
- delete[] tmp;
- return result;
-}
-
-void MortevielleEngine::hirs() {
- // Note: The original used this to set the graphics mode and clear the screen, both at
- // the start of the game, and whenever the screen need to be cleared. As such, this
- // method is deprecated in favour of clearing the screen
- debugC(1, kMortevielleCore, "TODO: hirs is deprecated in favour of ScreenSurface::clearScreen");
-
- if (_currGraphicalDevice == MODE_TANDY) {
- _screenSurface.fillRect(0, Common::Rect(0, 0, 639, 200));
- _resolutionScaler = 1;
- } else if (_currGraphicalDevice == MODE_CGA) {
- palette(1);
- _resolutionScaler = 1;
- } else
- _resolutionScaler = 2;
-
- _screenSurface.clearScreen();
-}
-
-/**
- * Init room : Cave or Cellar
- * @remarks Originally called 'cavegre'
- */
-void MortevielleEngine::initCaveOrCellar() {
- _coreVar._faithScore += 2;
- if (_coreVar._faithScore > 69)
- _coreVar._faithScore += (_coreVar._faithScore / 10);
- clearVerbBar();
- prepareScreenType2();
- displayTextInVerbBar(getEngineString(S_SOMEONE_ENTERS));
- int rand = (getRandomNumber(0, 4)) - 2;
- _speechManager.startSpeech(2, rand, 1);
-
- // The original was doing here a useless loop.
- // It has been removed
-
- clearVerbBar();
- displayAloneText();
-}
-
-/**
- * Display control menu string
- * @remarks Originally called 'tctrm'
- */
-void MortevielleEngine::displayControlMenu() {
- handleDescriptionText(2, (3000 + _controlMenu));
- _controlMenu = 0;
-}
-
-void MortevielleEngine::pictout(int seg, int dep, int x, int y) {
- GfxSurface surface;
- surface.decode(&_mem[seg * 16 + dep]);
-
- if (_currGraphicalDevice == MODE_HERCULES) {
- _mem[0x7000 * 16 + 2] = 0;
- _mem[0x7000 * 16 + 32] = 15;
- }
-
- if ((_caff != 51) && (READ_LE_UINT16(&_mem[0x7000 * 16 + 0x4138]) > 0x100))
- WRITE_LE_UINT16(&_mem[0x7000 * 16 + 0x4138], 0x100);
-
- _screenSurface.drawPicture(surface, x, y);
-}
-
-void MortevielleEngine::adzon() {
- Common::File f;
-
- if (!f.open("don.mor"))
- error("Missing file - don.mor");
-
- f.read(_tabdon, 7 * 256);
- f.close();
-
- if (!f.open("bmor.mor"))
- error("Missing file - bmor.mor");
-
- f.read(&_tabdon[kFleche], 1 * 1916);
- f.close();
-
- if (!f.open("dec.mor"))
- error("Missing file - dec.mor");
-
- f.read(&_mem[0x73a2 * 16 + 0], 1 * 1664);
- f.close();
-}
-
-/**
- * Returns the offset within the compressed image data resource of the desired image
- */
-int MortevielleEngine::animof(int ouf, int num) {
- int nani = _mem[kAdrAni * 16 + 1];
- int aux = num;
- if (ouf != 1)
- aux += nani;
-
- int animof_result = (nani << 2) + 2 + READ_BE_UINT16(&_mem[kAdrAni * 16 + (aux << 1)]);
-
- return animof_result;
-}
-
-/**
- * Display text in description bar
- * @remarks Originally called 'text1'
- */
-void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int mesgId) {
- int co;
-
- if (_resolutionScaler == 1)
- co = 10;
- else
- co = 6;
- Common::String tmpStr = getString(mesgId);
- if ((y == 182) && ((int) tmpStr.size() * co > nb * 6))
- y = 176;
- _text.displayStr(tmpStr, x, y, nb, 20, _textColor);
-}
-
-/**
- * Display description text
- * @remarks Originally called 'repon'
- */
-void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
- if ((mesgId > 499) && (mesgId < 563)) {
- Common::String tmpStr = getString(mesgId - 501 + kInventoryStringIndex);
-
- if ((int) tmpStr.size() > ((58 + (_resolutionScaler - 1) * 37) << 1))
- _largestClearScreen = true;
- else
- _largestClearScreen = false;
-
- clearDescriptionBar();
- _text.displayStr(tmpStr, 8, 176, 85, 3, 5);
- } else {
- mapMessageId(mesgId);
- switch (f) {
- case 2:
- case 8:
- clearDescriptionBar();
- prepareScreenType2();
- displayTextInDescriptionBar(8, 182, 103, mesgId);
- if ((mesgId == 68) || (mesgId == 69))
- _coreVar._availableQuestion[40] = '*';
- if ((mesgId == 104) && (_caff == CELLAR)) {
- _coreVar._availableQuestion[36] = '*';
- if (_coreVar._availableQuestion[39] == '*') {
- _coreVar._pctHintFound[3] = '*';
- _coreVar._availableQuestion[38] = '*';
- }
- }
- break;
- case 1:
- case 6:
- case 9: {
- int i;
- if ((f == 1) || (f == 6))
- i = 4;
- else
- i = 5;
-
- Common::String tmpStr = getString(mesgId);
- _text.displayStr(tmpStr, 80, 40, 60, 25, i);
-
- if (mesgId == 180)
- _coreVar._pctHintFound[6] = '*';
- else if (mesgId == 179)
- _coreVar._pctHintFound[10] = '*';
- }
- break;
- default:
- break;
- }
- }
-}
-
-/**
- * Recompute message Id
- * @remarks Originally called 'modif'
- */
-void MortevielleEngine::mapMessageId(int &mesgId) {
- if (mesgId == 26)
- mesgId = 25;
- else if ((mesgId > 29) && (mesgId < 36))
- mesgId -= 4;
- else if ((mesgId > 69) && (mesgId < 78))
- mesgId -= 37;
- else if ((mesgId > 99) && (mesgId < 194))
- mesgId -= 59;
- else if ((mesgId > 996) && (mesgId < 1000))
- mesgId -= 862;
- else if ((mesgId > 1500) && (mesgId < 1507))
- mesgId -= 1363;
- else if ((mesgId > 1507) && (mesgId < 1513))
- mesgId -= 1364;
- else if ((mesgId > 1999) && (mesgId < 2002))
- mesgId -= 1851;
- else if (mesgId == 2010)
- mesgId = 151;
- else if ((mesgId > 2011) && (mesgId < 2025))
- mesgId -= 1860;
- else if (mesgId == 2026)
- mesgId = 165;
- else if ((mesgId > 2029) && (mesgId < 2037))
- mesgId -= 1864;
- else if ((mesgId > 3000) && (mesgId < 3005))
- mesgId -= 2828;
- else if (mesgId == 4100)
- mesgId = 177;
- else if (mesgId == 4150)
- mesgId = 178;
- else if ((mesgId > 4151) && (mesgId < 4156))
- mesgId -= 3973;
- else if (mesgId == 4157)
- mesgId = 183;
- else if ((mesgId == 4160) || (mesgId == 4161))
- mesgId -= 3976;
-}
-
-/**
- * Initialize open objects array
- * @remarks Originally called 'initouv'
- */
-void MortevielleEngine::resetOpenObjects() {
- for (int cx = 1; cx <= 7; ++cx)
- _openObjects[cx] = 0;
- _openObjCount = 0;
-}
-
-void MortevielleEngine::ecr2(Common::String text) {
- // Some dead code was present in the original: removed
- _screenSurface.putxy(8, 177);
- int tlig = 59 + (_resolutionScaler - 1) * 36;
-
- if ((int)text.size() < tlig)
- _screenSurface.drawString(text, 5);
- else if ((int)text.size() < (tlig << 1)) {
- _screenSurface.putxy(8, 176);
- _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
- _screenSurface.putxy(8, 182);
- _screenSurface.drawString(copy(text, tlig, tlig << 1), 5);
- } else {
- _largestClearScreen = true;
- clearDescriptionBar();
- _screenSurface.putxy(8, 176);
- _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
- _screenSurface.putxy(8, 182);
- _screenSurface.drawString(copy(text, tlig, ((tlig << 1) - 1)), 5);
- _screenSurface.putxy(8, 190);
- _screenSurface.drawString(copy(text, tlig << 1, tlig * 3), 5);
- }
-}
-
-void MortevielleEngine::displayTextInVerbBar(Common::String text) {
- clearVerbBar();
- _screenSurface.putxy(8, 192);
- _screenSurface.drawString(text, 5);
-}
-
-/**
- * Display item in hand
- * @remarks Originally called 'modobj'
- */
-void MortevielleEngine::displayItemInHand(int objId) {
- Common::String strp = Common::String(' ');
-
- if (objId != 500)
- strp = getString(objId - 501 + kInventoryStringIndex);
-
- _menu.setText(_menu._inventoryMenu[8], strp);
- _menu.disableMenuItem(_menu._inventoryMenu[8]);
-}
-
-/**
- * Display empty hand
- * @remarks Originally called 'maivid'
- */
-void MortevielleEngine::displayEmptyHand() {
- _coreVar._selectedObjectId = 0;
- displayItemInHand(500);
-}
-
-/**
- * Set a random presence: Leo or Max
- * @remarks Originally called 'chlm'
- */
-int MortevielleEngine::checkLeoMaxRandomPresence() {
- int retval = getRandomNumber(1, 2);
- if (retval == 2)
- retval = 128;
-
- return retval;
-}
-
-/**
- * Reset room variables
- * @remarks Originally called 'debloc'
- */
-void MortevielleEngine::resetRoomVariables(int roomId) {
- _num = 0;
- _x = 0;
- _y = 0;
- if ((roomId != ROOM26) && (roomId != LANDING))
- resetPresenceInRooms(roomId);
- _savedBitIndex = _currBitIndex;
-}
-
-/**
- * Compute presence stats
- * @remarks Originally called 'ecfren'
- */
-int MortevielleEngine::getPresenceStats(int &rand, int cf, int roomId) {
- if (roomId == OWN_ROOM)
- displayAloneText();
- int retVal = -500;
- rand = 0;
- if ( ((roomId == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
- || ((roomId == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) )
- retVal = getPresenceStatsGreenRoom();
- if ((roomId == PURPLE_ROOM) && (!_purpleRoomPresenceLeo) && (!_room9PresenceLeo))
- retVal = getPresenceStatsPurpleRoom();
- if ( ((roomId == TOILETS) && (!_toiletsPresenceBobMax))
- || ((roomId == BATHROOM) && (!_bathRoomPresenceBobMax)) )
- retVal = getPresenceStatsToilets();
- if ((roomId == BLUE_ROOM) && (!_roomPresenceMax))
- retVal = getPresenceStatsBlueRoom();
- if ( ((roomId == RED_ROOM) && (!_roomPresenceBob))
- || ((roomId == GREEN_ROOM2) && (!_roomPresencePat)))
- retVal = getPresenceStatsRedRoom();
- if ((roomId == ROOM9) && (!_room9PresenceLeo) && (!_purpleRoomPresenceLeo))
- retVal = 10;
- if ( ((roomId == PURPLE_ROOM) && (_room9PresenceLeo))
- || ((roomId == ROOM9) && (_purpleRoomPresenceLeo)))
- retVal = -400;
- if (retVal != -500) {
- retVal += cf;
- rand = getRandomNumber(1, 100);
- }
-
- return retVal;
-}
-
-/**
- * Set presence flags
- * @remarks Originally called 'becfren'
- */
-void MortevielleEngine::setPresenceFlags(int roomId) {
- if ((roomId == GREEN_ROOM) || (roomId == DARKBLUE_ROOM)) {
- int rand = getRandomNumber(1, 2);
- if (roomId == GREEN_ROOM) {
- if (rand == 1)
- _roomPresenceLuc = true;
- else
- _roomPresenceIda = true;
- } else { // roomId == DARKBLUE_ROOM
- if (rand == 1)
- _roomPresenceGuy = true;
- else
- _roomPresenceEva = true;
- }
- } else if (roomId == PURPLE_ROOM)
- _purpleRoomPresenceLeo = true;
- else if (roomId == TOILETS)
- _toiletsPresenceBobMax = true;
- else if (roomId == BLUE_ROOM)
- _roomPresenceMax = true;
- else if (roomId == RED_ROOM)
- _roomPresenceBob = true;
- else if (roomId == BATHROOM)
- _bathRoomPresenceBobMax = true;
- else if (roomId == GREEN_ROOM2)
- _roomPresencePat = true;
- else if (roomId == ROOM9)
- _room9PresenceLeo = true;
-}
-
-void MortevielleEngine::init_nbrepm() {
- static const byte ipm[9] = { 0, 4, 5, 6, 7, 5, 6, 5, 8 };
-
- for (int idx = 0; idx < 9; ++idx)
- _nbrepm[idx] = ipm[idx];
-}
-
-void MortevielleEngine::phaz(int &rand, int &p, int cf) {
- p += cf;
- rand = getRandomNumber(1, 100);
-}
-
-/**
- * Get Presence
- * @remarks Originally called 't11'
- */
-int MortevielleEngine::getPresence(int roomId) {
- int retVal = 0;
- int rand;
-
- int p = getPresenceStats(rand, _coreVar._faithScore, roomId);
- _place = roomId;
- if ((roomId > OWN_ROOM) && (roomId < DINING_ROOM)) {
- if (p != -500) {
- if (rand > p) {
- displayAloneText();
- retVal = 0;
- } else {
- setPresenceFlags(_place);
- retVal = getPresenceBitIndex(_place);
- }
- } else
- retVal = getPresenceBitIndex(_place);
- }
-
- if (roomId > ROOM9) {
- if ((roomId > LANDING) && (roomId != CHAPEL) && (roomId != ROOM26))
- displayAloneText();
- else {
- int h = 0;
- if (roomId == DINING_ROOM)
- p = getPresenceStatsDiningRoom(h);
- else if (roomId == BUREAU)
- p = getPresenceStatsBureau(h);
- else if (roomId == KITCHEN)
- p = getPresenceStatsKitchen();
- else if ((roomId == ATTIC) || (roomId == CELLAR))
- p = getPresenceStatsAttic();
- else if ((roomId == LANDING) || (roomId == ROOM26))
- p = getPresenceStatsLanding();
- else if (roomId == CHAPEL)
- p = getPresenceStatsChapel(h);
- p += _coreVar._faithScore;
- rand = getRandomNumber(1, 100);
- if (rand > p) {
- displayAloneText();
- retVal = 0;
- } else {
- if (roomId == DINING_ROOM)
- p = setPresenceDiningRoom(h);
- else if (roomId == BUREAU)
- p = setPresenceBureau(h);
- else if ((roomId == KITCHEN) || (roomId == ATTIC) || (roomId == CELLAR))
- p = setPresenceKitchen();
- else if ((roomId == LANDING) || (roomId == ROOM26))
- p = setPresenceLanding();
- else if (roomId == CHAPEL)
- p = setPresenceChapel(h);
- retVal = p;
- }
- }
- }
-
- return retVal;
-}
-
-void MortevielleEngine::writetp(Common::String s, int t) {
- if (_resolutionScaler == 2)
- _screenSurface.drawString(s, t);
- else
- _screenSurface.drawString(copy(s, 1, 25), t);
-}
-
-void MortevielleEngine::aniof(int ouf, int num) {
- if ((_caff == BATHROOM) && ((num == 4) || (num == 5)))
- return;
-
- if ((_caff == DINING_ROOM) && (num == 7))
- num = 6;
- else if (_caff == KITCHEN) {
- if (num == 3)
- num = 4;
- else if (num == 4)
- num = 3;
- }
-
- int ad = kAdrAni;
- int offset = animof(ouf, num);
-
- GfxSurface surface;
- surface.decode(&_mem[ad * 16 + offset]);
- _screenSurface.drawPicture(surface, 0, 12);
-
- prepareScreenType1();
-}
-
-/**
- * Draw Picture
- * @remarks Originally called 'dessin'
- */
-void MortevielleEngine::drawPicture() {
- clearUpperLeftPart();
- if (_caff > 99) {
- draw(kAdrDes, 60, 33);
- _screenSurface.drawBox(118, 32, 291, 121, 15); // Medium box
- } else if (_caff > 69) {
- draw(kAdrDes, 112, 48); // Heads
- _screenSurface.drawBox(222, 47, 155, 91, 15);
- } else {
- draw(kAdrDes, 0, 12);
- prepareScreenType1();
- if ((_caff < 30) || (_caff > 32)) {
- for (int cx = 1; cx <= 6; ++cx) {
- if (_openObjects[cx] != 0)
- aniof(1, _openObjects[cx]);
- }
-
- if (_caff == ATTIC) {
- if (_coreVar._atticBallHoleObjectId == 141)
- aniof(1, 7);
-
- if (_coreVar._atticRodHoleObjectId == 159)
- aniof(1, 6);
- } else if ((_caff == CELLAR) && (_coreVar._cellarObjectId == 151))
- aniof(1, 2);
- else if ((_caff == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143))
- aniof(1, 1);
- else if ((_caff == WELL) && (_coreVar._wellObjectId != 0))
- aniof(1, 1);
- }
-
- if (_caff < ROOM26)
- startMusicOrSpeech(1);
- }
-}
-
-void MortevielleEngine::drawPictureWithText() {
- _text.taffich();
- drawPicture();
- _destinationOk = false;
-}
-
-/**
- * Engine function - Place
- * @remarks Originally called 'tkey1'
- */
-void MortevielleEngine::testKey(bool d) {
- bool quest = false;
- int x, y;
- bool click;
-
- _mouse.hideMouse();
- fenat('K');
-
- // Wait for release from any key or mouse button
- while (keyPressed())
- _key = testou();
-
- do {
- _mouse.getMousePosition(x, y, click);
- keyPressed();
- } while (click);
-
- // Event loop
- do {
- if (d)
- prepareRoom();
- quest = keyPressed();
- _mouse.getMousePosition(x, y, click);
- if (shouldQuit())
- return;
- } while (!(quest || (click) || (d && _anyone)));
- if (quest)
- testou();
- setMouseClick(false);
- _mouse.showMouse();
-}
-
-void MortevielleEngine::tlu(int af, int ob) {
- _caff = 32;
- drawPictureWithText();
- handleDescriptionText(6, ob + 4000);
- handleDescriptionText(2, 999);
- testKey(true);
- _caff = af;
- _msg[3] = OPCODE_NONE;
- _crep = 998;
-}
-
-void MortevielleEngine::affrep() {
- _caff = _coreVar._currPlace;
- _crep = _coreVar._currPlace;
-}
-
-/**
- * Exit room
- * @remarks Originally called 'tsort'
- */
-void MortevielleEngine::exitRoom() {
- if ((_openObjCount > 0) && (_coreVar._currPlace != OWN_ROOM)) {
- if (_coreVar._faithScore < 50)
- _coreVar._faithScore += 2;
- else
- _coreVar._faithScore += (_coreVar._faithScore / 10);
- }
-
- resetOpenObjects();
-
- _roomDoorId = OWN_ROOM;
- _mchai = 0;
- resetRoomVariables(_coreVar._currPlace);
-}
-
-/**
- * get 'read' description
- * @remarks Originally called 'st4'
- */
-void MortevielleEngine::getReadDescription(int objId) {
- _crep = 997;
-
- switch (objId) {
- case 114 :
- _crep = 109;
- break;
- case 110 :
- _crep = 107;
- break;
- case 158 :
- _crep = 113;
- break;
- case 152:
- case 153:
- case 154:
- case 155:
- case 156:
- case 150:
- case 100:
- case 157:
- case 160:
- case 161 :
- tlu(_caff, objId);
- break;
- default:
- break;
- }
-}
-
-/**
- * get 'search' description
- * @remarks Originally called 'st7'
- */
-void MortevielleEngine::getSearchDescription(int objId) {
- switch (objId) {
- case 116:
- case 144:
- _crep = 104;
- break;
- case 126:
- case 111:
- _crep = 108;
- break;
- case 132:
- _crep = 111;
- break;
- case 142:
- _crep = 112;
- break;
- default:
- _crep = 183;
- getReadDescription(objId);
- }
-}
-
-void MortevielleEngine::mennor() {
- _menu.menuUp(_msg[3]);
-}
-
-void MortevielleEngine::premtet() {
- draw(kAdrDes, 10, 80);
- _screenSurface.drawBox(18, 79, 155, 91, 15);
-}
-
-void MortevielleEngine::ajchai() {
- int cy = kAcha + ((_mchai - 1) * 10) - 1;
- int cx = 0;
- do {
- ++cx;
- } while ((cx <= 9) && (_tabdon[cy + cx] != 0));
-
- if (_tabdon[cy + cx] == 0)
- _tabdon[cy + cx] = _coreVar._selectedObjectId;
- else
- _crep = 192;
-}
-
-/**
- * Check if inventory is full and, if not, add object in it.
- * @remarks Originally called 'ajjer'
- */
-void MortevielleEngine::addObjectToInventory(int objectId) {
- int i = 0;
- do {
- ++i;
- } while ((i <= 5) && (_coreVar._inventory[i] != 0));
-
- if (_coreVar._inventory[i] == 0) {
- _coreVar._inventory[i] = objectId;
- _menu.setInventoryText();
- } else
- // Inventory is full
- _crep = 139;
-}
-
-/**
- * Interact with NPC
- * @remarks Originally called 'quelquun'
- */
-void MortevielleEngine::interactNPC() {
- if (_menu._menuDisplayed)
- _menu.eraseMenu();
-
- endSearch();
- _crep = 997;
-L1:
- if (!_hiddenHero) {
- if (_crep == 997)
- _crep = 138;
- handleDescriptionText(2, _crep);
- if (_crep == 138)
- _speechManager.startSpeech(5, 2, 1);
- else
- _speechManager.startSpeech(4, 4, 1);
-
- if (_openObjCount == 0)
- _coreVar._faithScore += 2;
- else if (_coreVar._faithScore < 50)
- _coreVar._faithScore += 4;
- else
- _coreVar._faithScore += 3 * (_coreVar._faithScore / 10);
- exitRoom();
- _menu.setDestinationText(LANDING);
- int cx = convertBitIndexToCharacterIndex(_currBitIndex);
- _caff = 69 + cx;
- _crep = _caff;
- _msg[3] = MENU_DISCUSS;
- _msg[4] = _menu._discussMenu[cx];
- _syn = true;
- _col = true;
- } else {
- if (getRandomNumber(1, 3) == 2) {
- _hiddenHero = false;
- _crep = 137;
- goto L1;
- } else {
- handleDescriptionText(2, 136);
- int rand = (getRandomNumber(0, 4)) - 2;
- _speechManager.startSpeech(3, rand, 1);
- clearDescriptionBar();
- displayAloneText();
- resetRoomVariables(MANOR_FRONT);
- affrep();
- }
- }
- if (_menu._menuDisplayed)
- _menu.drawMenu();
-}
-
-void MortevielleEngine::tsuiv() {
- int tbcl;
- int cy = kAcha + ((_mchai - 1) * 10) - 1;
- int cx = 0;
- do {
- ++cx;
- ++_searchCount;
- int cl = cy + _searchCount;
- tbcl = _tabdon[cl];
- } while ((tbcl == 0) && (_searchCount <= 9));
-
- if ((tbcl != 0) && (_searchCount < 11)) {
- _caff = tbcl;
- _crep = _caff + 400;
- if (_currBitIndex != 0)
- _coreVar._faithScore += 2;
- } else {
- affrep();
- endSearch();
- if (cx > 9)
- _crep = 131;
- }
-}
-
-void MortevielleEngine::tfleche() {
- bool qust;
- char touch;
-
- if (_num == 9999)
- return;
-
- fenat(chr(152));
- bool inRect = false;
- do {
- touch = '\0';
-
- do {
- _mouse.moveMouse(qust, touch);
- if (shouldQuit())
- return;
-
- if (getMouseClick())
- inRect = (_mouse._pos.x < 256 * _resolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
- prepareRoom();
- } while (!(qust || inRect || _anyone));
-
- if (qust && (touch == '\103'))
- _dialogManager.show(_hintPctMessage, 1);
- } while (!((touch == '\73') || ((touch == '\104') && (_x != 0) && (_y != 0)) || (_anyone) || (inRect)));
-
- if (touch == '\73')
- _keyPressedEsc = true;
-
- if (inRect) {
- _x = _mouse._pos.x;
- _y = _mouse._pos.y;
- }
-}
-
-/**
- * Set coordinates
- * @remarks Originally called 'tcoord'
- */
-void MortevielleEngine::setCoordinates(int sx) {
- int sy, ix, iy;
- int ib;
-
-
- _num = 0;
- _crep = 999;
- int a = 0;
- int atdon = kAmzon + 3;
- int cy = 0;
- while (cy < _caff) {
- a += _tabdon[atdon];
- atdon += 4;
- ++cy;
- }
-
- if (_tabdon[atdon] == 0) {
- _crep = 997;
- return;
- }
-
- a += kFleche;
- int cb = 0;
- for (cy = 0; cy <= (sx - 2); ++cy) {
- ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
- cb += (ib * 4) + 2;
- }
- ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
- if (ib == 0) {
- _crep = 997;
- return;
- }
-
- cy = 1;
- do {
- cb += 2;
- sx = _tabdon[a + cb] * _resolutionScaler;
- sy = _tabdon[(a + cb + 1)];
- cb += 2;
- ix = _tabdon[a + cb] * _resolutionScaler;
- iy = _tabdon[(a + cb + 1)];
- ++cy;
- } while (!(((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) || (cy > ib)));
-
- if ((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) {
- _num = cy - 1;
- return;
- }
-
- _crep = 997;
-}
-
-void MortevielleEngine::treg(int objId) {
- int mdes = _caff;
- _caff = objId;
-
- if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_msg[4] == OPCODE_SLOOK)) {
- drawPictureWithText();
- if ((_caff > 29) && (_caff < 33))
- handleDescriptionText(2, _caff);
- else
- handleDescriptionText(2, _caff + 400);
- testKey(true);
- _caff = mdes;
- _msg[3] = 0;
- _crep = 998;
- } else {
- _obpart = true;
- _crep = _caff + 400;
- _menu.setSearchMenu();
- }
-}
-
-/**
- * Engine function - Put in hand
- * @remarks Originally called 'avpoing'
- */
-void MortevielleEngine::putInHand(int &objId) {
- _crep = 999;
- if (_coreVar._selectedObjectId != 0)
- addObjectToInventory(_coreVar._selectedObjectId);
-
- // If inventory wasn't full
- if (_crep != 139) {
- displayItemInHand(objId + 400);
- _coreVar._selectedObjectId = objId;
- objId = 0;
- }
-}
-
-void MortevielleEngine::rechai(int &ch) {
- int tmpPlace = _coreVar._currPlace;
-
- if (_coreVar._currPlace == CRYPT)
- tmpPlace = CELLAR;
- ch = _tabdon[kAchai + (tmpPlace * 7) + _num - 1];
-}
-
-/**
- * Check before leaving the secret passage
- * @remarks Originally called 't23coul'
- */
-int MortevielleEngine::checkLeaveSecretPassage() {
- if (!checkInventory(143)) {
- _crep = 1512;
- loseGame();
- }
-
- return CELLAR;
-}
-
-void MortevielleEngine::fenat(char ans) {
- int coul;
-
- _mouse.hideMouse();
- if (_currGraphicalDevice == MODE_CGA)
- coul = 2;
- else if (_currGraphicalDevice == MODE_HERCULES)
- coul = 1;
- else
- coul = 12;
-
- _screenSurface.writeCharacter(Common::Point(306, 193), ord(ans), coul);
- _screenSurface.drawBox(300, 191, 16, 8, 15);
- _mouse.showMouse();
-}
-
-/**
- * Test Keyboard
- * @remarks Originally called 'teskbd'
- */
-void MortevielleEngine::testKeyboard() {
- if (keyPressed())
- testou();
-}
-
-int MortevielleEngine::testou() {
- char ch = getChar();
-
- switch (ch) {
- case '\23' :
- _soundOff = !_soundOff;
- break;
- case '\26' :
- if ((_x26KeyCount == 1) || (_x26KeyCount == 2)) {
- decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
- ++_x26KeyCount;
-
- return 61;
- }
- break;
- case '\33' :
- if (keyPressed())
- ch = getChar();
- break;
- default:
- break;
- }
-
- return ord(ch);
-}
-
-void MortevielleEngine::sauvecr(int y, int dy) {
-// _mouse.hideMouse();
-// _mouse.showMouse();
-}
-
-void MortevielleEngine::charecr(int y, int dy) {
-// _mouse.hideMouse();
-// _mouse.showMouse();
-}
-
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/utils.cpp b/engines/mortevielle/utils.cpp
new file mode 100644
index 0000000000..f2d0c952dc
--- /dev/null
+++ b/engines/mortevielle/utils.cpp
@@ -0,0 +1,3454 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Mortville Manor DOS source code
+ * Copyright (c) 1987-1989 Lankhor
+ */
+
+#include "common/scummsys.h"
+#include "graphics/cursorman.h"
+
+#include "mortevielle/dialogs.h"
+#include "mortevielle/menu.h"
+#include "mortevielle/mortevielle.h"
+#include "mortevielle/mouse.h"
+#include "mortevielle/outtext.h"
+#include "mortevielle/speech.h"
+
+namespace Mortevielle {
+
+/**
+ * Check is a key was pressed
+ * It also delays the engine and check if the screen has to be updated
+ * @remarks Originally called 'keypressed'
+ */
+bool MortevielleEngine::keyPressed() {
+ // Check for any pending key presses
+ handleEvents();
+
+ // Check if it's time to draw the next frame
+ if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
+ _lastGameFrame = g_system->getMillis();
+
+ _screenSurface.updateScreen();
+
+ _debugger.onFrame();
+ }
+
+ // Delay briefly to keep CPU usage down
+ g_system->delayMillis(5);
+
+ // Return if there are any pending key presses
+ return !_keypresses.empty();
+}
+
+/**
+ * Wait for a keypress
+ * @remarks Originally called 'get_ch'
+ */
+int MortevielleEngine::getChar() {
+ // If there isn't any pending keypress, wait until there is
+ while (!shouldQuit() && _keypresses.empty()) {
+ keyPressed();
+ }
+
+ // Return the top keypress
+ return shouldQuit() ? 0 : _keypresses.pop();
+}
+
+/**
+ * Handle pending events
+ * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
+ * the mouse Y position is divided by 2 to keep the game thinking the Y goes from 0 - 199
+ */
+bool MortevielleEngine::handleEvents() {
+ Common::Event event;
+ if (!g_system->getEventManager()->pollEvent(event))
+ return false;
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_LBUTTONUP:
+ case Common::EVENT_MOUSEMOVE:
+ _mousePos = Common::Point(event.mouse.x, event.mouse.y / 2);
+ _mouse._pos.x = event.mouse.x;
+ _mouse._pos.y = event.mouse.y / 2;
+
+ if (event.type == Common::EVENT_LBUTTONDOWN)
+ _mouseClick = true;
+ else if (event.type == Common::EVENT_LBUTTONUP)
+ _mouseClick = false;
+
+ break;
+ case Common::EVENT_KEYDOWN:
+ addKeypress(event);
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * Add the specified key to the pending keypress stack
+ */
+void MortevielleEngine::addKeypress(Common::Event &evt) {
+ // Character to add
+ char ch = evt.kbd.ascii;
+
+ // Check for debugger
+ if ((evt.kbd.keycode == Common::KEYCODE_d) && (evt.kbd.flags & Common::KBD_CTRL)) {
+ // Attach to the debugger
+ _debugger.attach();
+ _debugger.onFrame();
+ } else if ((evt.kbd.keycode >= Common::KEYCODE_a) && (evt.kbd.keycode <= Common::KEYCODE_z)) {
+ // Handle alphabetic keys
+ if (evt.kbd.hasFlags(Common::KBD_CTRL))
+ ch = evt.kbd.keycode - Common::KEYCODE_a + 1;
+ else
+ ch = evt.kbd.keycode - Common::KEYCODE_a + 'A';
+ } else if ((evt.kbd.keycode >= Common::KEYCODE_F1) && (evt.kbd.keycode <= Common::KEYCODE_F12)) {
+ // Handle function keys
+ ch = 59 + evt.kbd.keycode - Common::KEYCODE_F1;
+ } else {
+ // Series of special cases
+ switch (evt.kbd.keycode) {
+ case Common::KEYCODE_KP4:
+ case Common::KEYCODE_LEFT:
+ ch = '4';
+ break;
+ case Common::KEYCODE_KP2:
+ case Common::KEYCODE_DOWN:
+ ch = '2';
+ break;
+ case Common::KEYCODE_KP6:
+ case Common::KEYCODE_RIGHT:
+ ch = '6';
+ break;
+ case Common::KEYCODE_KP8:
+ case Common::KEYCODE_UP:
+ ch = '8';
+ break;
+ case Common::KEYCODE_KP7:
+ ch = '7';
+ break;
+ case Common::KEYCODE_KP1:
+ ch = '1';
+ break;
+ case Common::KEYCODE_KP9:
+ ch = '9';
+ break;
+ case Common::KEYCODE_KP3:
+ ch = '3';
+ break;
+ case Common::KEYCODE_KP5:
+ ch = '5';
+ break;
+ case Common::KEYCODE_RETURN:
+ ch = '\13';
+ break;
+ case Common::KEYCODE_ESCAPE:
+ ch = '\33';
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ch != 0)
+ _keypresses.push(ch);
+}
+
+
+static byte CURSOR_ARROW_DATA[16 * 16] = {
+ 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x0f, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/**
+ * Initialize the mouse
+ */
+void MortevielleEngine::initMouse() {
+ CursorMan.replaceCursor(CURSOR_ARROW_DATA, 16, 16, 0, 0, 0xff);
+ CursorMan.showMouse(true);
+
+ _mouse.initMouse();
+}
+
+/**
+ * Sets the mouse position
+ * @remarks Since the ScummVM screen surface is double height to handle 640x200 using 640x400,
+ * the mouse Y position is doubled to convert from 0-199 to 0-399
+ */
+void MortevielleEngine::setMousePos(const Common::Point &pt) {
+ // Adjust the passed position from simulated 640x200 to 640x400 co-ordinates
+ Common::Point newPoint(pt.x, (pt.y == 199) ? 399 : pt.y * 2);
+
+ if (newPoint != _mousePos)
+ // Warp the mouse to the new position
+ g_system->warpMouse(newPoint.x, newPoint.y);
+
+ // Save the new position
+ _mousePos = newPoint;
+}
+
+/**
+ * Delay by a given amount
+ */
+void MortevielleEngine::delay(int amount) {
+ uint32 endTime = g_system->getMillis() + amount;
+
+ while (g_system->getMillis() < endTime) {
+ if (g_system->getMillis() > (_lastGameFrame + GAME_FRAME_DELAY)) {
+ _lastGameFrame = g_system->getMillis();
+ _screenSurface.updateScreen();
+
+ _debugger.onFrame();
+ }
+
+ g_system->delayMillis(10);
+ }
+}
+
+/**
+ * Waits for the user to select an action, and then handles it
+ * @remarks Originally called tecran
+ */
+void MortevielleEngine::handleAction() {
+ const int lim = 20000;
+ int temps = 0;
+ char inkey = '\0';
+ bool oo, funct = 0;
+
+ clearVerbBar();
+ oo = false;
+ _controlMenu = 0;
+ if (!_keyPressedEsc) {
+ _menu.drawMenu();
+ _menu._menuDisplayed = true;
+ temps = 0;
+ _key = 0;
+ funct = false;
+ inkey = '.';
+
+ _inMainGameLoop = true;
+ do {
+ _menu.updateMenu();
+ prepareRoom();
+ _mouse.moveMouse(funct, inkey);
+ if (shouldQuit())
+ return;
+ ++temps;
+ } while (!((_menu._menuSelected) || (temps > lim) || (funct) || (_anyone)));
+ _inMainGameLoop = false;
+
+ _menu.eraseMenu();
+ _menu._menuDisplayed = false;
+ if ((inkey == '\1') || (inkey == '\3') || (inkey == '\5') || (inkey == '\7') || (inkey == '\11')) {
+ changeGraphicalDevice((uint)(ord(inkey) - 1) >> 1);
+ return;
+ }
+ if (_menu._menuSelected && (_msg[3] == MENU_SAVE)) {
+ Common::String saveName = Common::String::format("Savegame #%d", _msg[4] & 15);
+ _savegameManager.saveGame(_msg[4] & 15, saveName);
+ }
+ if (_menu._menuSelected && (_msg[3] == MENU_LOAD))
+ _savegameManager.loadGame((_msg[4] & 15) - 1);
+ if (inkey == '\103') { /* F9 */
+ temps = _dialogManager.show(_hintPctMessage, 1);
+ return;
+ } else if (inkey == '\77') {
+ if ((_menuOpcode != OPCODE_NONE) && ((_msg[3] == MENU_ACTION) || (_msg[3] == MENU_SELF))) {
+ _msg[4] = _menuOpcode;
+ displayTextInVerbBar(getEngineString(S_IDEM));
+ } else
+ return;
+ } else if (inkey == '\104') {
+ if ((_x != 0) && (_y != 0))
+ _num = 9999;
+ return;
+ }
+ }
+ if (inkey == '\73') {
+ _quitGame = true;
+ hourToChar();
+ } else {
+ if ((funct) && (inkey != '\77'))
+ return;
+ if (temps > lim) {
+ handleDescriptionText(2, 141);
+ if (_num == 9999)
+ _num = 0;
+ } else {
+ _menuOpcode = _msg[3];
+ if ((_msg[3] == MENU_ACTION) || (_msg[3] == MENU_SELF))
+ _menuOpcode = _msg[4];
+ if (!_anyone) {
+ if ((_heroSearching) || (_obpart)) {
+ if (_mouse._pos.y < 12)
+ return;
+
+ if ((_msg[4] == OPCODE_SOUND) || (_msg[4] == OPCODE_LIFT)) {
+ oo = true;
+ if ((_msg[4] == OPCODE_LIFT) || (_obpart)) {
+ endSearch();
+ _caff = _coreVar._currPlace;
+ _crep = 998;
+ } else
+ tsuiv();
+ mennor();
+ }
+ }
+ }
+ do {
+ if (! oo)
+ handleOpcode();
+
+ if ((_controlMenu == 0) && (! _loseGame) && (! _endGame)) {
+ _text.taffich();
+ if (_destinationOk) {
+ _destinationOk = false;
+ drawPicture();
+ }
+ if ((!_syn) || (_col))
+ handleDescriptionText(2, _crep);
+ }
+ } while (_syn);
+ if (_controlMenu != 0)
+ displayControlMenu();
+ }
+ }
+}
+
+/**
+ * Engine function - Init Places
+ * @remarks Originally called 'init_lieu'
+ */
+void MortevielleEngine::loadPlaces() {
+ Common::File f;
+
+ if (!f.open("MXX.mor"))
+ if (!f.open("MFXX.mor"))
+ error("Missing file - MXX.mor");
+
+ for (int i = 0; i < 7; ++i) {
+ for (int j = 0; j < 25; ++j)
+ _destinationArray[i][j] = f.readByte();
+ }
+
+ f.close();
+}
+
+/**
+ * Set Text Color
+ * @remarks Originally called 'text_color'
+ */
+void MortevielleEngine::setTextColor(int col) {
+ _textColor = col;
+}
+
+/**
+ * Prepare screen - Type 1!
+ * @remarks Originally called 'ecrf1'
+ */
+void MortevielleEngine::prepareScreenType1() {
+ // Large drawing
+ _screenSurface.drawBox(0, 11, 512, 163, 15);
+}
+
+/**
+ * Prepare room - Type 2!
+ * @remarks Originally called 'ecrf2'
+ */
+void MortevielleEngine::prepareScreenType2() {
+ setTextColor(5);
+}
+
+/**
+ * Prepare room - Type 3!
+ * @remarks Originally called 'ecrf7'
+ */
+void MortevielleEngine::prepareScreenType3() {
+ setTextColor(4);
+}
+
+/**
+ * Engine function - Update hour
+ * @remarks Originally called 'calch'
+ */
+void MortevielleEngine::updateHour(int &day, int &hour, int &minute) {
+ int newHour = readclock();
+ int th = _currentHourCount + ((newHour - _currentDayHour) / _inGameHourDuration);
+ minute = ((th % 2) + _currHalfHour) * 30;
+ hour = ((uint)th >> 1) + _currHour;
+ if (minute == 60) {
+ minute = 0;
+ ++hour;
+ }
+ day = (hour / 24) + _currDay;
+ hour = hour - ((day - _currDay) * 24);
+}
+
+/**
+ * Engine function - Convert character index to bit index
+ * @remarks Originally called 'conv'
+ */
+int MortevielleEngine::convertCharacterIndexToBitIndex(int characterIndex) {
+ return 128 >> (characterIndex - 1);
+}
+
+/**
+ * Engine function - Convert bit index to character index
+ * @remarks Originally called 'tip'
+ */
+int MortevielleEngine::convertBitIndexToCharacterIndex(int bitIndex) {
+ int retVal = 0;
+
+ if (bitIndex == 128)
+ retVal = 1;
+ else if (bitIndex == 64)
+ retVal = 2;
+ else if (bitIndex == 32)
+ retVal = 3;
+ else if (bitIndex == 16)
+ retVal = 4;
+ else if (bitIndex == 8)
+ retVal = 5;
+ else if (bitIndex == 4)
+ retVal = 6;
+ else if (bitIndex == 2)
+ retVal = 7;
+ else if (bitIndex == 1)
+ retVal = 8;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Reset presence in other rooms
+ * @remarks Originally called 't5'
+ */
+void MortevielleEngine::resetPresenceInRooms(int roomId) {
+ if (roomId == DINING_ROOM)
+ _blo = false;
+
+ if (roomId != GREEN_ROOM) {
+ _roomPresenceLuc = false;
+ _roomPresenceIda = false;
+ }
+
+ if (roomId != PURPLE_ROOM)
+ _purpleRoomPresenceLeo = false;
+
+ if (roomId != DARKBLUE_ROOM) {
+ _roomPresenceGuy = false;
+ _roomPresenceEva = false;
+ }
+
+ if (roomId != BLUE_ROOM)
+ _roomPresenceMax = false;
+ if (roomId != RED_ROOM)
+ _roomPresenceBob = false;
+ if (roomId != GREEN_ROOM2)
+ _roomPresencePat = false;
+ if (roomId != TOILETS)
+ _toiletsPresenceBobMax = false;
+ if (roomId != BATHROOM)
+ _bathRoomPresenceBobMax = false;
+ if (roomId != ROOM9)
+ _room9PresenceLeo = false;
+}
+
+/**
+ * Engine function - Show the people present in the given room
+ * @remarks Originally called 'affper'
+ */
+void MortevielleEngine::showPeoplePresent(int bitIndex) {
+ int xp = 580 - (_screenSurface.getStringWidth("LEO") / 2);
+
+ for (int i = 1; i <= 8; ++i)
+ _menu.disableMenuItem(_menu._discussMenu[i]);
+
+ clearUpperRightPart();
+ if ((bitIndex & 128) == 128) {
+ _screenSurface.putxy(xp, 24);
+ _screenSurface.drawString("LEO", 4);
+ _menu.enableMenuItem(_menu._discussMenu[1]);
+ }
+ if ((bitIndex & 64) == 64) {
+ _screenSurface.putxy(xp, 32);
+ _screenSurface.drawString("PAT", 4);
+ _menu.enableMenuItem(_menu._discussMenu[2]);
+ }
+ if ((bitIndex & 32) == 32) {
+ _screenSurface.putxy(xp, 40);
+ _screenSurface.drawString("GUY", 4);
+ _menu.enableMenuItem(_menu._discussMenu[3]);
+ }
+ if ((bitIndex & 16) == 16) {
+ _screenSurface.putxy(xp, 48);
+ _screenSurface.drawString("EVA", 4);
+ _menu.enableMenuItem(_menu._discussMenu[4]);
+ }
+ if ((bitIndex & 8) == 8) {
+ _screenSurface.putxy(xp, 56);
+ _screenSurface.drawString("BOB", 4);
+ _menu.enableMenuItem(_menu._discussMenu[5]);
+ }
+ if ((bitIndex & 4) == 4) {
+ _screenSurface.putxy(xp, 64);
+ _screenSurface.drawString("LUC", 4);
+ _menu.enableMenuItem(_menu._discussMenu[6]);
+ }
+ if ((bitIndex & 2) == 2) {
+ _screenSurface.putxy(xp, 72);
+ _screenSurface.drawString("IDA", 4);
+ _menu.enableMenuItem(_menu._discussMenu[7]);
+ }
+ if ((bitIndex & 1) == 1) {
+ _screenSurface.putxy(xp, 80);
+ _screenSurface.drawString("MAX", 4);
+ _menu.enableMenuItem(_menu._discussMenu[8]);
+ }
+ _currBitIndex = bitIndex;
+}
+
+/**
+ * Engine function - Select random characters
+ * @remarks Originally called 'choix'
+ */
+int MortevielleEngine::selectCharacters(int min, int max) {
+ bool invertSelection = false;
+ int rand = getRandomNumber(min, max);
+
+ if (rand > 4) {
+ rand = 8 - rand;
+ invertSelection = true;
+ }
+
+ int i = 0;
+ int retVal = 0;
+ while (i < rand) {
+ int charIndex = getRandomNumber(1, 8);
+ int charBitIndex = convertCharacterIndexToBitIndex(charIndex);
+ if ((retVal & charBitIndex) != charBitIndex) {
+ ++i;
+ retVal |= charBitIndex;
+ }
+ }
+ if (invertSelection)
+ retVal = 255 - retVal;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Green Room
+ * @remarks Originally called 'cpl1'
+ */
+int MortevielleEngine::getPresenceStatsGreenRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ // The original uses an || instead of an &&, resulting
+ // in an always true condition. Based on the other tests,
+ // and on other scenes, we use an && instead.
+ if ((hour > 7) && (hour < 11))
+ retVal = 25;
+ else if ((hour > 10) && (hour < 14))
+ retVal = 35;
+ else if ((hour > 13) && (hour < 16))
+ retVal = 50;
+ else if ((hour > 15) && (hour < 18))
+ retVal = 5;
+ else if ((hour > 17) && (hour < 22))
+ retVal = 35;
+ else if ((hour > 21) && (hour < 24))
+ retVal = 50;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 70;
+
+ _menu.updateMenu();
+
+ return retVal;
+}
+/**
+ * Engine function - Get Presence Statistics - Purple Room
+ * @remarks Originally called 'cpl2'
+ */
+int MortevielleEngine::getPresenceStatsPurpleRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 7) && (hour < 11))
+ retVal = -2;
+ else if (hour == 11)
+ retVal = 100;
+ else if ((hour > 11) && (hour < 23))
+ retVal = 10;
+ else if (hour == 23)
+ retVal = 20;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 50;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Toilets
+ * @remarks Originally called 'cpl3'
+ */
+int MortevielleEngine::getPresenceStatsToilets() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 10)) || ((hour > 19) && (hour < 24)))
+ retVal = 34;
+ else if (((hour > 9) && (hour < 20)) || ((hour >= 0) && (hour < 9)))
+ retVal = 0;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Blue Room
+ * @remarks Originally called 'cpl5'
+ */
+int MortevielleEngine::getPresenceStatsBlueRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 6) && (hour < 10))
+ retVal = 0;
+ else if (hour == 10)
+ retVal = 100;
+ else if ((hour > 10) && (hour < 24))
+ retVal = 15;
+ else if ((hour >= 0) && (hour < 7))
+ retVal = 50;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Red Room
+ * @remarks Originally called 'cpl6'
+ */
+int MortevielleEngine::getPresenceStatsRedRoom() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 7) && (hour < 13)) || ((hour > 17) && (hour < 20)))
+ retVal = -2;
+ else if (((hour > 12) && (hour < 17)) || ((hour > 19) && (hour < 24)))
+ retVal = 35;
+ else if (hour == 17)
+ retVal = 100;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 60;
+
+ return retVal;
+}
+
+/**
+ * Shows the "you are alone" message in the status area
+ * on the right hand side of the screen
+ * @remarks Originally called 'person'
+ */
+void MortevielleEngine::displayAloneText() {
+ for (int cf = 1; cf <= 8; ++cf)
+ _menu.disableMenuItem(_menu._discussMenu[cf]);
+
+ Common::String sYou = getEngineString(S_YOU);
+ Common::String sAre = getEngineString(S_ARE);
+ Common::String sAlone = getEngineString(S_ALONE);
+
+ clearUpperRightPart();
+ _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sYou) / 2), 30);
+ _screenSurface.drawString(sYou, 4);
+ _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAre) / 2), 50);
+ _screenSurface.drawString(sAre, 4);
+ _screenSurface.putxy(580 - (_screenSurface.getStringWidth(sAlone) / 2), 70);
+ _screenSurface.drawString(sAlone, 4);
+
+ _currBitIndex = 0;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Bureau
+ * @remarks Originally called 'cpl10'
+ */
+int MortevielleEngine::getPresenceStatsDiningRoom(int &hour) {
+ int day, minute;
+
+ int retVal = 0;
+ updateHour(day, hour, minute);
+ if (((hour > 7) && (hour < 11)) || ((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
+ retVal = 100;
+ else if ((hour == 11) || ((hour > 20) && (hour < 24)))
+ retVal = 45;
+ else if (((hour > 13) && (hour < 17)) || (hour == 18))
+ retVal = 35;
+ else if (hour == 17)
+ retVal = 60;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = 5;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Bureau
+ * @remarks Originally called 'cpl11'
+ */
+int MortevielleEngine::getPresenceStatsBureau(int &hour) {
+ int day, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 12)) || ((hour > 20) && (hour < 24)))
+ retVal = 25;
+ else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21)))
+ retVal = 5;
+ else if ((hour > 13) && (hour < 17))
+ retVal = 55;
+ else if ((hour > 16) && (hour < 19))
+ retVal = 45;
+ else if ((hour >= 0) && (hour < 9))
+ retVal = 0;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Kitchen
+ * @remarks Originally called 'cpl12'
+ */
+int MortevielleEngine::getPresenceStatsKitchen() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (((hour > 8) && (hour < 15)) || ((hour > 16) && (hour < 22)))
+ retVal = 55;
+ else if (((hour > 14) && (hour < 17)) || ((hour > 21) && (hour < 24)))
+ retVal = 25;
+ else if ((hour >= 0) && (hour < 5))
+ retVal = 0;
+ else if ((hour > 4) && (hour < 9))
+ retVal = 15;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Attic
+ * @remarks Originally called 'cpl13'
+ */
+int MortevielleEngine::getPresenceStatsAttic() {
+ return 0;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Landing
+ * @remarks Originally called 'cpl15'
+ */
+int MortevielleEngine::getPresenceStatsLanding() {
+ int day, hour, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if ((hour > 7) && (hour < 12))
+ retVal = 25;
+ else if ((hour > 11) && (hour < 14))
+ retVal = 0;
+ else if ((hour > 13) && (hour < 18))
+ retVal = 10;
+ else if ((hour > 17) && (hour < 20))
+ retVal = 55;
+ else if ((hour > 19) && (hour < 22))
+ retVal = 5;
+ else if ((hour > 21) && (hour < 24))
+ retVal = 15;
+ else if ((hour >= 0) && (hour < 8))
+ retVal = -15;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get Presence Statistics - Room Chapel
+ * @remarks Originally called 'cpl20'
+ */
+int MortevielleEngine::getPresenceStatsChapel(int &hour) {
+ int day, minute;
+ int retVal = 0;
+
+ updateHour(day, hour, minute);
+ if (hour == 10)
+ retVal = 65;
+ else if ((hour > 10) && (hour < 21))
+ retVal = 5;
+ else if ((hour > 20) && (hour < 24))
+ retVal = -15;
+ else if ((hour >= 0) && (hour < 5))
+ retVal = -300;
+ else if ((hour > 4) && (hour < 10))
+ retVal = -5;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Green Room
+ * @remarks Originally called 'quelq1'
+ */
+void MortevielleEngine::setPresenceGreenRoom(int roomId) {
+ int rand = getRandomNumber(1, 2);
+ if (roomId == GREEN_ROOM) {
+ if (rand == 1)
+ _roomPresenceLuc = true;
+ else
+ _roomPresenceIda = true;
+ } else if (roomId == DARKBLUE_ROOM) {
+ if (rand == 1)
+ _roomPresenceGuy = true;
+ else
+ _roomPresenceEva = true;
+ }
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Purple Room
+ * @remarks Originally called 'quelq2'
+ */
+void MortevielleEngine::setPresencePurpleRoom() {
+ if (_place == PURPLE_ROOM)
+ _purpleRoomPresenceLeo = true;
+ else
+ _room9PresenceLeo = true;
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Blue Room
+ * @remarks Originally called 'quelq5'
+ */
+void MortevielleEngine::setPresenceBlueRoom() {
+ _roomPresenceMax = true;
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Red Room
+ * @remarks Originally called 'quelq6'
+ */
+void MortevielleEngine::setPresenceRedRoom(int roomId) {
+ if (roomId == RED_ROOM)
+ _roomPresenceBob = true;
+ else if (roomId == GREEN_ROOM2)
+ _roomPresencePat = true;
+
+ _currBitIndex = 10;
+}
+
+/**
+ * Engine function - Check who is in the Dining Room
+ * @remarks Originally called 'quelq10'
+ */
+int MortevielleEngine::setPresenceDiningRoom(int hour) {
+ int retVal = 0;
+
+ if ((hour >= 0) && (hour < 8))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if ((hour > 7) && (hour < 10)) {
+ min = 5;
+ max = 7;
+ } else if ((hour > 9) && (hour < 12)) {
+ min = 1;
+ max = 4;
+ } else if (((hour > 11) && (hour < 15)) || ((hour > 18) && (hour < 21))) {
+ min = 6;
+ max = 8;
+ } else if (((hour > 14) && (hour < 19)) || ((hour > 20) && (hour < 24))) {
+ min = 1;
+ max = 5;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Bureau
+ * @remarks Originally called 'quelq11'
+ */
+int MortevielleEngine::setPresenceBureau(int hour) {
+ int retVal = 0;
+
+ if ((hour >= 0) && (hour < 8))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if (((hour > 7) && (hour < 10)) || ((hour > 20) && (hour < 24))) {
+ min = 1;
+ max = 3;
+ } else if (((hour > 9) && (hour < 12)) || ((hour > 13) && (hour < 19))) {
+ min = 1;
+ max = 4;
+ } else if (((hour > 11) && (hour < 14)) || ((hour > 18) && (hour < 21))) {
+ min = 1;
+ max = 2;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Kitchen
+ * @remarks Originally called 'quelq12'
+ */
+int MortevielleEngine::setPresenceKitchen() {
+ int retVal = checkLeoMaxRandomPresence();
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the Landing
+ * @remarks Originally called 'quelq15'
+ */
+int MortevielleEngine::setPresenceLanding() {
+ bool test = false;
+ int rand = 0;
+ do {
+ rand = getRandomNumber(1, 8);
+ test = (((rand == 1) && (_purpleRoomPresenceLeo || _room9PresenceLeo)) ||
+ ((rand == 2) && _roomPresencePat) ||
+ ((rand == 3) && _roomPresenceGuy) ||
+ ((rand == 4) && _roomPresenceEva) ||
+ ((rand == 5) && _roomPresenceBob) ||
+ ((rand == 6) && _roomPresenceLuc) ||
+ ((rand == 7) && _roomPresenceIda) ||
+ ((rand == 8) && _roomPresenceMax));
+ } while (test);
+
+ int retVal = convertCharacterIndexToBitIndex(rand);
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Check who is in the chapel
+ * @remarks Originally called 'quelq20'
+ */
+int MortevielleEngine::setPresenceChapel(int hour) {
+ int retVal = 0;
+
+ if (((hour >= 0) && (hour < 10)) || ((hour > 18) && (hour < 24)))
+ retVal = checkLeoMaxRandomPresence();
+ else {
+ int min = 0, max = 0;
+ if ((hour > 9) && (hour < 12)) {
+ min = 3;
+ max = 7;
+ } else if ((hour > 11) && (hour < 18)) {
+ min = 1;
+ max = 2;
+ } else if (hour == 18) {
+ min = 2;
+ max = 4;
+ }
+ retVal = selectCharacters(min, max);
+ }
+ showPeoplePresent(retVal);
+
+ return retVal;
+}
+
+/**
+ * Engine function - Get the answer after you known a door
+ * @remarks Originally called 'frap'
+ */
+void MortevielleEngine::getKnockAnswer() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if ((hour >= 0) && (hour < 8))
+ _crep = 190;
+ else {
+ if (getRandomNumber(1, 100) > 70)
+ _crep = 190;
+ else
+ _crep = 147;
+ }
+}
+
+/**
+ * Engine function - Get Room Presence Bit Index
+ * @remarks Originally called 'nouvp'
+ */
+int MortevielleEngine::getPresenceBitIndex(int roomId) {
+ int bitIndex = 0;
+ if (roomId == GREEN_ROOM) {
+ if (_roomPresenceLuc)
+ bitIndex = 4; // LUC
+ if (_roomPresenceIda)
+ bitIndex = 2; // IDA
+ } else if ( ((roomId == PURPLE_ROOM) && (_purpleRoomPresenceLeo))
+ || ((roomId == ROOM9) && (_room9PresenceLeo)))
+ bitIndex = 128; // LEO
+ else if (roomId == DARKBLUE_ROOM) {
+ if (_roomPresenceGuy)
+ bitIndex = 32; // GUY
+ if (_roomPresenceEva)
+ bitIndex = 16; // EVA
+ } else if ((roomId == BLUE_ROOM) && (_roomPresenceMax))
+ bitIndex = 1; // MAX
+ else if ((roomId == RED_ROOM) && (_roomPresenceBob))
+ bitIndex = 8; // BOB
+ else if ((roomId == GREEN_ROOM2) && (_roomPresencePat))
+ bitIndex = 64; // PAT
+ else if ( ((roomId == TOILETS) && (_toiletsPresenceBobMax))
+ || ((roomId == BATHROOM) && (_bathRoomPresenceBobMax)) )
+ bitIndex = 9; // BOB + MAX
+
+ if (bitIndex != 9)
+ showPeoplePresent(bitIndex);
+
+ return bitIndex;
+}
+
+/**
+ * Engine function - initGame
+ * @remarks Originally called 'dprog'
+ */
+void MortevielleEngine::initGame() {
+ _place = MANOR_FRONT;
+ _currentHourCount = 0;
+ if (!_coreVar._alreadyEnteredManor)
+ _blo = true;
+ _inGameHourDuration = kTime1;
+ _currentDayHour = readclock();
+}
+
+/**
+ * Engine function - Set Random Presence - Green Room
+ * @remarks Originally called 'pl1'
+ */
+void MortevielleEngine::setRandomPresenceGreenRoom(int cf) {
+ if ( ((_place == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
+ || ((_place == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) ) {
+ int p = getPresenceStatsGreenRoom();
+ int rand;
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceGreenRoom(_place);
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Purple Room
+ * @remarks Originally called 'pl2'
+ */
+void MortevielleEngine::setRandomPresencePurpleRoom(int cf) {
+ if (!_purpleRoomPresenceLeo) {
+ int p = getPresenceStatsPurpleRoom();
+ int rand;
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresencePurpleRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Blue Room
+ * @remarks Originally called 'pl5'
+ */
+void MortevielleEngine::setRandomPresenceBlueRoom(int cf) {
+ if (!_roomPresenceMax) {
+ int p = getPresenceStatsBlueRoom();
+ int rand;
+
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceBlueRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Red Room
+ * @remarks Originally called 'pl6'
+ */
+void MortevielleEngine::setRandomPresenceRedRoom(int cf) {
+ if ( ((_place == RED_ROOM) && (!_roomPresenceBob))
+ || ((_place == GREEN_ROOM2) && (!_roomPresencePat)) ) {
+ int p = getPresenceStatsRedRoom();
+ int rand;
+
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceRedRoom(_place);
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Room 9
+ * @remarks Originally called 'pl9'
+ */
+void MortevielleEngine::setRandomPresenceRoom9(int cf) {
+ if (!_room9PresenceLeo) {
+ cf = -10;
+ int p, rand;
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresencePurpleRoom();
+ }
+}
+
+/**
+ * Engine function - Set Random Presence - Dining Room
+ * @remarks Originally called 'pl10'
+ */
+void MortevielleEngine::setRandomPresenceDiningRoom(int cf) {
+ int h, rand;
+ int p = getPresenceStatsDiningRoom(h);
+ phaz(rand, p, cf);
+
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceDiningRoom(h);
+}
+
+/**
+ * Engine function - Set Random Presence - Bureau
+ * @remarks Originally called 'pl11'
+ */
+void MortevielleEngine::setRandomPresenceBureau(int cf) {
+ int h, rand;
+
+ int p = getPresenceStatsBureau(h);
+ phaz(rand, p, cf);
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceBureau(h);
+}
+
+/**
+ * Engine function - Set Random Presence - Kitchen
+ * @remarks Originally called 'pl12'
+ */
+void MortevielleEngine::setRandomPresenceKitchen(int cf) {
+ int p, rand;
+
+ p = getPresenceStatsKitchen();
+ phaz(rand, p, cf);
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceKitchen();
+}
+
+/**
+ * Engine function - Set Random Presence - Attic / Cellar
+ * @remarks Originally called 'pl13'
+ */
+void MortevielleEngine::setRandomPresenceAttic(int cf) {
+ int p, rand;
+
+ p = getPresenceStatsAttic();
+ phaz(rand, p, cf);
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceKitchen();
+}
+
+/**
+ * Engine function - Set Random Presence - Landing
+ * @remarks Originally called 'pl15'
+ */
+void MortevielleEngine::setRandomPresenceLanding(int cf) {
+ int p, rand;
+
+ p = getPresenceStatsLanding();
+ phaz(rand, p, cf);
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceLanding();
+}
+
+/**
+ * Engine function - Set Random Presence - Chapel
+ * @remarks Originally called 'pl20'
+ */
+void MortevielleEngine::setRandomPresenceChapel(int cf) {
+ int h, rand;
+
+ int p = getPresenceStatsChapel(h);
+ phaz(rand, p, cf);
+ if (rand > p)
+ displayAloneText();
+ else
+ setPresenceChapel(h);
+}
+
+/**
+ * Start music or speech
+ * @remarks Originally called 'musique'
+ */
+void MortevielleEngine::startMusicOrSpeech(int so) {
+ if (so == 0) {
+ /* musik(0) */
+ ;
+ } else if ((!_introSpeechPlayed) && (!_coreVar._alreadyEnteredManor)) {
+ // Type 1: Speech
+ _speechManager.startSpeech(10, 1, 1);
+ _introSpeechPlayed = true;
+ } else {
+ if (((_coreVar._currPlace == MOUNTAIN) || (_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) && (getRandomNumber(1, 3) == 2))
+ // Type 1: Speech
+ _speechManager.startSpeech(9, getRandomNumber(2, 4), 1);
+ else if ((_coreVar._currPlace == CHAPEL) && (getRandomNumber(1, 2) == 1))
+ // Type 1: Speech
+ _speechManager.startSpeech(8, 1, 1);
+ else if ((_coreVar._currPlace == WELL) && (getRandomNumber(1, 2) == 2))
+ // Type 1: Speech
+ _speechManager.startSpeech(12, 1, 1);
+ else if (_coreVar._currPlace == INSIDE_WELL)
+ // Type 1: Speech
+ _speechManager.startSpeech(13, 1, 1);
+ else
+ // Type 2 : music
+ _speechManager.startSpeech(getRandomNumber(1, 17), 1, 2);
+ }
+}
+
+/**
+ * Engine function - You lose!
+ * @remarks Originally called 'tperd'
+ */
+void MortevielleEngine::loseGame() {
+ resetOpenObjects();
+ _roomDoorId = OWN_ROOM;
+ _mchai = 0;
+ _menu.unsetSearchMenu();
+ if (!_blo)
+ getPresence(MANOR_FRONT);
+
+ _loseGame = true;
+ clearUpperLeftPart();
+ _screenSurface.drawBox(60, 35, 400, 50, 15);
+ handleDescriptionText(9, _crep);
+ clearDescriptionBar();
+ clearVerbBar();
+ _col = false;
+ _syn = false;
+ _destinationOk = false;
+}
+
+/**
+ * Engine function - Check inventory for a given object
+ * @remarks Originally called 'cherjer'
+ */
+bool MortevielleEngine::checkInventory(int objectId) {
+ bool retVal = false;
+ for (int i = 1; i <= 6; ++i)
+ retVal = (retVal || (_coreVar._inventory[i] == objectId));
+
+ if (_coreVar._selectedObjectId == objectId)
+ retVal = true;
+
+ return retVal;
+}
+
+/**
+ * Engine function - Display Dining Room
+ * @remarks Originally called 'st1sama'
+ */
+void MortevielleEngine::displayDiningRoom() {
+ _coreVar._currPlace = DINING_ROOM;
+ affrep();
+}
+
+/**
+ * Engine function - Start non interactive Dialog
+ * @remarks Originally called 'sparl'
+ */
+void MortevielleEngine::startDialog(int16 rep) {
+ const int haut[9] = { 0, 0, 1, -3, 6, -2, 2, 7, -1 };
+ int key;
+
+ assert(rep >= 0);
+
+ _mouse.hideMouse();
+ Common::String dialogStr = getString(rep + kDialogStringIndex);
+ _text.displayStr(dialogStr, 230, 4, 65, 24, 5);
+ _dialogManager.drawF3F8();
+
+ key = 0;
+ do {
+ _speechManager.startSpeech(rep, haut[_caff - 69], 0);
+ key = _dialogManager.waitForF3F8();
+ if (shouldQuit())
+ return;
+ } while (key != 66);
+ hirs();
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - End of Search: reset globals
+ * @remarks Originally called 'finfouill'
+ */
+void MortevielleEngine::endSearch() {
+ _heroSearching = false;
+ _obpart = false;
+ _searchCount = 0;
+ _menu.unsetSearchMenu();
+}
+
+/**
+ * Engine function - Go to Dining room
+ * @remarks Originally called 't1sama'
+ */
+void MortevielleEngine::gotoDiningRoom() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if ((hour < 5) && (_coreVar._currPlace > ROOM18)) {
+ if (!checkInventory(137)) { //You don't have the keys, and it's late
+ _crep = 1511;
+ loseGame();
+ } else
+ displayDiningRoom();
+ } else if (!_coreVar._alreadyEnteredManor) { //Is it your first time?
+ _currBitIndex = 255; // Everybody is present
+ showPeoplePresent(_currBitIndex);
+ _caff = 77;
+ drawPictureWithText();
+ _screenSurface.drawBox(223, 47, 155, 91, 15);
+ handleDescriptionText(2, 33);
+ testKey(false);
+ mennor();
+ _mouse.hideMouse();
+ hirs();
+ premtet();
+ startDialog(140);
+ drawRightFrame();
+ drawClock();
+ _mouse.showMouse();
+ _coreVar._currPlace = OWN_ROOM;
+ affrep();
+ resetPresenceInRooms(DINING_ROOM);
+ if (!_blo)
+ getPresence(OWN_ROOM);
+ _currBitIndex = 0;
+ _savedBitIndex = 0;
+ _coreVar._alreadyEnteredManor = true;
+ } else
+ displayDiningRoom();
+}
+
+/**
+ * Engine function - Check Manor distance (in the mountains)
+ * @remarks Originally called 't1neig'
+ */
+void MortevielleEngine::checkManorDistance() {
+ ++_manorDistance;
+ if (_manorDistance > 2) {
+ _crep = 1506;
+ loseGame();
+ } else {
+ _destinationOk = true;
+ _coreVar._currPlace = MOUNTAIN;
+ affrep();
+ }
+}
+
+/**
+ * Engine function - Go to Manor front
+ * @remarks Originally called 't1deva'
+ */
+void MortevielleEngine::gotoManorFront() {
+ _manorDistance = 0;
+ _coreVar._currPlace = MANOR_FRONT;
+ affrep();
+}
+
+/**
+ * Engine function - Go to Manor back
+ * @remarks Originally called 't1derr'
+ */
+void MortevielleEngine::gotoManorBack() {
+ _coreVar._currPlace = MANOR_BACK;
+ affrep();
+}
+
+/**
+ * Engine function - Dead : Flooded in Well
+ * @remarks Originally called 't1deau'
+ */
+void MortevielleEngine::floodedInWell() {
+ _crep = 1503;
+ loseGame();
+}
+
+/**
+ * Engine function - Change Graphical Device
+ * @remarks Originally called 'change_gd'
+ */
+void MortevielleEngine::changeGraphicalDevice(int newDevice) {
+ _mouse.hideMouse();
+ _currGraphicalDevice = newDevice;
+ hirs();
+ _mouse.initMouse();
+ _mouse.showMouse();
+ drawRightFrame();
+ prepareRoom();
+ drawClock();
+ if (_currBitIndex != 0)
+ showPeoplePresent(_currBitIndex);
+ else
+ displayAloneText();
+ clearDescriptionBar();
+ clearVerbBar();
+ _maff = 68;
+ drawPictureWithText();
+ handleDescriptionText(2, _crep);
+ _menu.displayMenu();
+}
+
+/**
+ * Called when a savegame has been loaded.
+ * @remarks Originally called 'antegame'
+ */
+void MortevielleEngine::gameLoaded() {
+ _mouse.hideMouse();
+ _menu._menuDisplayed = false;
+ _loseGame = true;
+ _anyone = false;
+ _destinationOk = true;
+ _col = false;
+ _hiddenHero = false;
+ _uptodatePresence = false;
+ _maff = 68;
+ _menuOpcode = OPCODE_NONE;
+ _introSpeechPlayed = false;
+ _x = 0;
+ _y = 0;
+ _num = 0;
+ _startHour = 0;
+ _endHour = 0;
+ _searchCount = 0;
+ _roomDoorId = OWN_ROOM;
+ _syn = true;
+ _heroSearching = true;
+ _mchai = 0;
+ _manorDistance = 0;
+ resetOpenObjects();
+ _takeObjCount = 0;
+ affrep();
+ _hintPctMessage = getString(580);
+
+ _destinationOk = false;
+ _endGame = true;
+ _loseGame = false;
+ _heroSearching = false;
+
+ displayAloneText();
+ prepareRoom();
+ drawClock();
+ drawPictureWithText();
+ handleDescriptionText(2, _crep);
+ clearVerbBar();
+ _endGame = false;
+ _menu.setDestinationText(_coreVar._currPlace);
+ _menu.setInventoryText();
+ if (_coreVar._selectedObjectId != 0)
+ displayItemInHand(_coreVar._selectedObjectId + 400);
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Handle OpCodes
+ * @remarks Originally called 'tsitu'
+ */
+void MortevielleEngine::handleOpcode() {
+ if (!_col)
+ clearDescriptionBar();
+ _syn = false;
+ _keyPressedEsc = false;
+ if (!_anyone) {
+ if (_uptodatePresence) {
+ if ((_msg[3] == MENU_MOVE) || (_msg[4] == OPCODE_LEAVE) || (_msg[4] == OPCODE_SLEEP) || (_msg[4] == OPCODE_EAT)) {
+ _controlMenu = 4;
+ mennor();
+ return;
+ }
+ }
+ if (_msg[3] == MENU_MOVE)
+ fctMove();
+ if (_msg[3] == MENU_DISCUSS)
+ fctDiscuss();
+ if (_msg[3] == MENU_INVENTORY)
+ fctInventoryTake();
+ if (_msg[4] == OPCODE_ATTACH)
+ fctAttach();
+ if (_msg[4] == OPCODE_WAIT)
+ fctWait();
+ if (_msg[4] == OPCODE_FORCE)
+ fctForce();
+ if (_msg[4] == OPCODE_SLEEP)
+ fctSleep();
+ if (_msg[4] == OPCODE_LISTEN)
+ fctListen();
+ if (_msg[4] == OPCODE_ENTER)
+ fctEnter();
+ if (_msg[4] == OPCODE_CLOSE)
+ fctClose();
+ if (_msg[4] == OPCODE_SEARCH)
+ fctSearch();
+ if (_msg[4] == OPCODE_KNOCK)
+ fctKnock();
+ if (_msg[4] == OPCODE_SCRATCH)
+ fctScratch();
+ if (_msg[4] == OPCODE_READ)
+ fctRead();
+ if (_msg[4] == OPCODE_EAT)
+ fctEat();
+ if (_msg[4] == OPCODE_PLACE)
+ fctPlace();
+ if (_msg[4] == OPCODE_OPEN)
+ fctOpen();
+ if (_msg[4] == OPCODE_TAKE)
+ fctTake();
+ if (_msg[4] == OPCODE_LOOK)
+ fctLook();
+ if (_msg[4] == OPCODE_SMELL)
+ fctSmell();
+ if (_msg[4] == OPCODE_SOUND)
+ fctSound();
+ if (_msg[4] == OPCODE_LEAVE)
+ fctLeave();
+ if (_msg[4] == OPCODE_LIFT)
+ fctLift();
+ if (_msg[4] == OPCODE_TURN)
+ fctTurn();
+ if (_msg[4] == OPCODE_SSEARCH)
+ fctSelfSearch();
+ if (_msg[4] == OPCODE_SREAD)
+ fctSelfRead();
+ if (_msg[4] == OPCODE_SPUT)
+ fctSelfPut();
+ if (_msg[4] == OPCODE_SLOOK)
+ fctSelftLook();
+ _hiddenHero = false;
+
+ if (_msg[4] == OPCODE_SHIDE)
+ fctSelfHide();
+ } else {
+ if (_anyone) {
+ interactNPC();
+ _anyone = false;
+ mennor();
+ return;
+ }
+ }
+ int hour, day, minute;
+ updateHour(day, hour, minute);
+ if ((((hour == 12) || (hour == 13) || (hour == 19)) && (_coreVar._currPlace != DINING_ROOM)) ||
+ ((hour > 0) && (hour < 6) && (_coreVar._currPlace != OWN_ROOM)))
+ ++_coreVar._faithScore;
+ if (((_coreVar._currPlace < CRYPT) || (_coreVar._currPlace > MOUNTAIN)) && (_coreVar._currPlace != INSIDE_WELL)
+ && (_coreVar._currPlace != OWN_ROOM) && (_coreVar._selectedObjectId != 152) && (!_loseGame)) {
+ if ((_coreVar._faithScore > 99) && (hour > 8) && (hour < 16)) {
+ _crep = 1501;
+ loseGame();
+ }
+ if ((_coreVar._faithScore > 99) && (hour > 0) && (hour < 9)) {
+ _crep = 1508;
+ loseGame();
+ }
+ if ((day > 1) && (hour > 8) && (!_loseGame)) {
+ _crep = 1502;
+ loseGame();
+ }
+ }
+ mennor();
+}
+
+/**
+ * Engine function - Transform time into a char
+ * @remarks Originally called 'tmaj3'
+ */
+void MortevielleEngine::hourToChar() {
+ int day, hour, minute;
+
+ updateHour(day, hour, minute);
+ if (minute == 30)
+ minute = 1;
+ hour += day * 24;
+ minute += hour * 2;
+ _coreVar._fullHour = chr(minute);
+}
+
+/**
+ * Engine function - extract time from a char
+ * @remarks Originally called 'theure'
+ */
+void MortevielleEngine::charToHour() {
+ int fullHour = ord(_coreVar._fullHour);
+ int tmpHour = fullHour % 48;
+ _currDay = fullHour / 48;
+ _currHalfHour = tmpHour % 2;
+ _currHour = tmpHour / 2;
+ _hour = _currHour;
+ if (_currHalfHour == 1)
+ _minute = 30;
+ else
+ _minute = 0;
+}
+
+/**
+ * Engine function - Clear upper left part of Screen - Type 1
+ * @remarks Originally called 'clsf1'
+ */
+void MortevielleEngine::clearUpperLeftPart() {
+ _mouse.hideMouse();
+ _screenSurface.fillRect(0, Common::Rect(0, 11, 514, 175));
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Clear low bar used by description
+ * @remarks Originally called 'clsf2'
+ */
+void MortevielleEngine::clearDescriptionBar() {
+ _mouse.hideMouse();
+ if (_largestClearScreen) {
+ _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 199));
+ _screenSurface.drawBox(0, 175, 634, 24, 15);
+ _largestClearScreen = false;
+ } else {
+ _screenSurface.fillRect(0, Common::Rect(1, 176, 633, 190));
+ _screenSurface.drawBox(0, 175, 634, 15, 15);
+ }
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Clear lowest bar used by verbs
+ * @remarks Originally called 'clsf3'
+ */
+void MortevielleEngine::clearVerbBar() {
+ _mouse.hideMouse();
+ _screenSurface.fillRect(0, Common::Rect(1, 192, 633, 199));
+ _screenSurface.drawBox(0, 191, 634, 8, 15);
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Clear upper right part of the screen
+ * @remarks Originally called 'clsf10'
+ */
+void MortevielleEngine::clearUpperRightPart() {
+ int x1, x2;
+ Common::String st;
+
+ _mouse.hideMouse();
+ if (_resolutionScaler == 1) {
+ x2 = 634;
+ x1 = 534;
+ } else {
+ x2 = 600;
+ x1 = 544;
+ }
+ // Clear ambiance description
+ _screenSurface.fillRect(15, Common::Rect(x1, 93, x2, 98));
+ if (_coreVar._faithScore < 33)
+ st = getEngineString(S_COOL);
+ else if (_coreVar._faithScore < 66)
+ st = getEngineString(S_LOURDE);
+ else if (_coreVar._faithScore > 65)
+ st = getEngineString(S_MALSAINE);
+
+ x1 = 580 - (_screenSurface.getStringWidth(st) / 2);
+ _screenSurface.putxy(x1, 92);
+ _screenSurface.drawString(st, 4);
+
+ // Clear person list
+ _screenSurface.fillRect(15, Common::Rect(560, 24, 610, 86));
+ _mouse.showMouse();
+}
+
+/**
+ * Engine function - Get a random number between two values
+ * @remarks Originally called 'get_random_number' and 'hazard'
+ */
+int MortevielleEngine::getRandomNumber(int minval, int maxval) {
+ return _randomSource.getRandomNumber(maxval - minval) + minval;
+}
+
+/**
+ * Engine function - Show alert "use move menu"
+ * @remarks Originally called 'aldepl'
+ */
+void MortevielleEngine::showMoveMenuAlert() {
+ _dialogManager.show(getEngineString(S_USE_DEP_MENU), 1);
+}
+
+/**
+ * The original engine used this method to display a starting text screen letting the player
+ * select the graphics mode to use
+ * @remarks Originally called 'dialpre'
+ */
+void MortevielleEngine::showConfigScreen() {
+ _crep = 998;
+}
+
+/**
+ * Decodes a number of 64 byte blocks
+ * @param pStart Start of data
+ * @param count Number of 64 byte blocks
+ * @remarks Originally called 'zzuul'
+ */
+void MortevielleEngine::decodeNumber(byte *pStart, int count) {
+ while (count-- > 0) {
+ for (int idx = 0; idx < 64; ++pStart, ++idx) {
+ uint16 v = ((*pStart - 0x80) << 1) + 0x80;
+
+ if (v & 0x8000)
+ *pStart = 0;
+ else if (v & 0xff00)
+ *pStart = 0xff;
+ else
+ *pStart = (byte)v;
+ }
+ }
+}
+
+const byte tabdr[32] = {
+ 32, 101, 115, 97, 114, 105, 110,
+ 117, 116, 111, 108, 13, 100, 99,
+ 112, 109, 46, 118, 130, 39, 102,
+ 98, 44, 113, 104, 103, 33, 76,
+ 85, 106, 30, 31
+};
+
+const byte tab30[32] = {
+ 69, 67, 74, 138, 133, 120, 77, 122,
+ 121, 68, 65, 63, 73, 80, 83, 82,
+ 156, 45, 58, 79, 49, 86, 78, 84,
+ 71, 81, 64, 66, 135, 34, 136, 91
+};
+
+const byte tab31[32]= {
+ 93, 47, 48, 53, 50, 70, 124, 75,
+ 72, 147, 140, 150, 151, 57, 56, 51,
+ 107, 139, 55, 89, 131, 37, 54, 88,
+ 119, 0, 0, 0, 0, 0, 0, 0
+};
+
+void MortevielleEngine::cinq_huit(char &c, int &idx, byte &pt, bool &the_end) {
+ uint16 oct, ocd;
+
+ /* 5-8 */
+ oct = _inpBuffer[idx];
+ oct = ((uint16)(oct << (16 - pt))) >> (16 - pt);
+ if (pt < 6) {
+ ++idx;
+ oct = oct << (5 - pt);
+ pt += 11;
+ oct = oct | ((uint)_inpBuffer[idx] >> pt);
+ } else {
+ pt -= 5;
+ oct = (uint)oct >> pt;
+ }
+
+ switch (oct) {
+ case 11:
+ c = '$';
+ the_end = true;
+ break;
+ case 30:
+ case 31:
+ ocd = _inpBuffer[idx];
+ ocd = (uint16)(ocd << (16 - pt)) >> (16 - pt);
+ if (pt < 6) {
+ ++idx;
+ ocd = ocd << (5 - pt);
+ pt += 11;
+ ocd = ocd | ((uint)_inpBuffer[idx] >> pt);
+ } else {
+ pt -= 5;
+ ocd = (uint)ocd >> pt;
+ }
+
+ if (oct == 30)
+ c = chr(tab30[ocd]);
+ else
+ c = chr(tab31[ocd]);
+
+ if (c == '\0') {
+ the_end = true;
+ c = '#';
+ }
+ break;
+ default:
+ c = chr(tabdr[oct]);
+ break;
+ }
+}
+
+/**
+ * Decode and extract the line with the given Id
+ * @remarks Originally called 'deline'
+ */
+Common::String MortevielleEngine::getString(int num) {
+ Common::String wrkStr = "";
+
+ if (num < 0) {
+ warning("getString(%d): num < 0! Skipping", num);
+ } else if (!_txxFileFl) {
+ wrkStr = getGameString(num);
+ } else {
+ int hint = _ntpBuffer[num]._hintId;
+ byte point = _ntpBuffer[num]._point;
+ int length = 0;
+ bool endFl = false;
+ char let;
+ do {
+ cinq_huit(let, hint, point, endFl);
+ wrkStr += let;
+ ++length;
+ } while (!endFl);
+ }
+
+ while (wrkStr.lastChar() == '$')
+ // Remove trailing '$'s
+ wrkStr.deleteLastChar();
+
+ return wrkStr;
+}
+
+void MortevielleEngine::copcha() {
+ for (int i = kAcha; i < kAcha + 390; i++)
+ _tabdon[i] = _tabdon[i + 390];
+}
+
+/**
+ * Engine function - When restarting the game, reset the main variables used by the engine
+ * @remarks Originally called 'inzon'
+ */
+void MortevielleEngine::resetVariables() {
+ copcha();
+
+ _coreVar._alreadyEnteredManor = false;
+ _coreVar._selectedObjectId = 0;
+ _coreVar._cellarObjectId = 0;
+ _coreVar._atticBallHoleObjectId = 0;
+ _coreVar._atticRodHoleObjectId = 0;
+ _coreVar._wellObjectId = 0;
+ _coreVar._secretPassageObjectId = 0;
+ _coreVar._purpleRoomObjectId = 136;
+ _coreVar._cryptObjectId = 141;
+ _coreVar._faithScore = getRandomNumber(4, 10);
+ _coreVar._currPlace = MANOR_FRONT;
+
+ for (int i = 2; i <= 6; ++i)
+ _coreVar._inventory[i] = 0;
+
+ // Only object in inventory: a gun
+ _coreVar._inventory[1] = 113;
+
+ _coreVar._fullHour = chr(20);
+
+ for (int i = 1; i <= 10; ++i)
+ _coreVar._pctHintFound[i] = ' ';
+
+ for (int i = 1; i <= 6; ++i)
+ _coreVar._availableQuestion[i] = '*';
+
+ for (int i = 7; i <= 9; ++i)
+ _coreVar._availableQuestion[i] = ' ';
+
+ for (int i = 10; i <= 28; ++i)
+ _coreVar._availableQuestion[i] = '*';
+
+ for (int i = 29; i <= 42; ++i)
+ _coreVar._availableQuestion[i] = ' ';
+
+ _coreVar._availableQuestion[33] = '*';
+
+ for (int i = 1; i <= 8; ++i)
+ _nbrep[i] = 0;
+
+ init_nbrepm();
+}
+
+/**
+ * Engine function - Set the palette
+ * @remarks Originally called 'writepal'
+ */
+void MortevielleEngine::setPal(int n) {
+ switch (_currGraphicalDevice) {
+ case MODE_TANDY:
+ case MODE_EGA:
+ case MODE_AMSTRAD1512:
+ for (int i = 1; i <= 16; ++i) {
+ _mem[(0x7000 * 16) + (2 * i)] = _stdPal[n][i].x;
+ _mem[(0x7000 * 16) + (2 * i) + 1] = _stdPal[n][i].y;
+ }
+ break;
+ case MODE_CGA: {
+ nhom pal[16];
+ for (int i = 0; i < 16; ++i) {
+ pal[i] = _cgaPal[n]._a[i];
+ }
+
+ if (n < 89)
+ palette(_cgaPal[n]._p);
+
+ for (int i = 0; i <= 15; ++i)
+ displayCGAPattern(i, _patternArr[pal[i]._id], pal);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Engine function - Display a CGA pattern, using a specified palette
+ * @remarks Originally called 'outbloc'
+ */
+void MortevielleEngine::displayCGAPattern(int n, Pattern p, nhom *pal) {
+ int addr = n * 404 + 0xd700;
+
+ WRITE_LE_UINT16(&_mem[0x6000 * 16 + addr], p._tax);
+ WRITE_LE_UINT16(&_mem[0x6000 * 16 + addr + 2], p._tay);
+ addr += 4;
+ for (int i = 0; i < p._tax; ++i) {
+ for (int j = 0; j < p._tay; ++j)
+ _mem[(0x6000 * 16) + addr + j * p._tax + i] = pal[n]._hom[p._des[i + 1][j + 1]];
+ }
+}
+
+/**
+ * Engine function - Load Palette from File
+ * @remarks Originally called 'charpal'
+ */
+void MortevielleEngine::loadPalette() {
+ Common::File f;
+ byte b;
+
+ if (!f.open("fxx.mor")) {
+ if (f.open("mfxx.mor"))
+ f.seek(7 * 25);
+ else
+ error("Missing file - fxx.mor");
+ }
+
+ for (int i = 0; i < 108; ++i)
+ _fxxBuffer[i] = f.readSint16LE();
+ f.close();
+
+ if (!f.open("plxx.mor"))
+ error("Missing file - plxx.mor");
+ for (int i = 0; i <= 90; ++i) {
+ for (int j = 1; j <= 16; ++j) {
+ _stdPal[i][j].x = f.readByte();
+ _stdPal[i][j].y = f.readByte();
+ }
+ }
+ f.close();
+
+ if (!f.open("cxx.mor"))
+ error("Missing file - cxx.mor");
+
+ for (int j = 0; j <= 90; ++j) {
+ _cgaPal[j]._p = f.readByte();
+ for (int i = 0; i <= 15; ++i) {
+ nhom &with = _cgaPal[j]._a[i];
+
+ b = f.readByte();
+ with._id = (uint)b >> 4;
+ with._hom[0] = ((uint)b >> 2) & 3;
+ with._hom[1] = b & 3;
+ }
+ }
+
+ _cgaPal[10]._a[9] = _cgaPal[10]._a[5];
+ for (int j = 0; j <= 14; ++j) {
+ _patternArr[j]._tax = f.readByte();
+ _patternArr[j]._tay = f.readByte();
+ for (int i = 1; i <= 20; ++i) {
+ for (int k = 1; k <= 20; ++k)
+ _patternArr[j]._des[i][k] = f.readByte();
+ }
+ }
+ f.close();
+}
+
+/**
+ * Engine function - Load Texts from File
+ * @remarks Originally called 'chartex'
+ */
+void MortevielleEngine::loadTexts() {
+ Common::File inpFile;
+ Common::File ntpFile;
+
+ _txxFileFl = false;
+ if (getLanguage() == Common::EN_ANY) {
+ warning("English version expected - Switching to DAT file");
+ return;
+ }
+
+ if (!inpFile.open("TXX.INP")) {
+ if (!inpFile.open("TXX.MOR")) {
+ warning("Missing file - TXX.INP or .MOR - Switching to DAT file");
+ return;
+ }
+ }
+ if (!ntpFile.open("TXX.NTP")) {
+ warning("Missing file - TXX.INP or .MOR - Switching to DAT file");
+ return;
+ }
+
+ if ((inpFile.size() > (kMaxTi * 2)) || (ntpFile.size() > (kMaxTd * 3))) {
+ warning("TXX file - Unexpected format - Switching to DAT file");
+ return;
+ }
+
+ for (int i = 0; i < inpFile.size() / 2; ++i)
+ _inpBuffer[i] = inpFile.readUint16LE();
+
+ inpFile.close();
+ _txxFileFl = true;
+
+ for (int i = 0; i < (ntpFile.size() / 3); ++i) {
+ _ntpBuffer[i]._hintId = ntpFile.readSint16LE();
+ _ntpBuffer[i]._point = ntpFile.readByte();
+ }
+
+ ntpFile.close();
+
+}
+
+void MortevielleEngine::loadBRUIT5() {
+ Common::File f;
+
+ if (!f.open("bruit5"))
+ error("Missing file - bruit5");
+
+ f.read(&_mem[kAdrNoise5 * 16 + 0], 149 * 128);
+ f.close();
+}
+
+void MortevielleEngine::loadCFIEC() {
+ Common::File f;
+
+ if (!f.open("cfiec.mor")) {
+ if (!f.open("alcfiec.mor"))
+ error("Missing file - *cfiec.mor");
+ }
+
+ _cfiecBufferSize = ((f.size() / 128) + 1) * 128;
+ int32 fileSize = f.size();
+
+ if (!_reloadCFIEC)
+ _cfiecBuffer = (byte *)malloc(sizeof(byte) * _cfiecBufferSize);
+
+ for (int32 i = 0; i < fileSize; ++i)
+ _cfiecBuffer[i] = f.readByte();
+
+ for (int i = fileSize; i < _cfiecBufferSize; i++)
+ _cfiecBuffer[i] = 0;
+
+ f.close();
+
+ _reloadCFIEC = false;
+}
+
+
+void MortevielleEngine::loadCFIPH() {
+ Common::File f;
+
+ if (!f.open("cfiph.mor")) {
+ if (!f.open("alcfiph.mor"))
+ error("Missing file - *cfiph.mor");
+ }
+
+ _speechManager._cfiphBuffer = (int16 *)malloc(sizeof(int16) * (f.size() / 2));
+
+ for (int i = 0; i < (f.size() / 2); ++i)
+ _speechManager._cfiphBuffer[i] = f.readSint16LE();
+
+ f.close();
+}
+
+/**
+ * Engine function - Play Music
+ * @remarks Originally called 'music'
+ */
+void MortevielleEngine::music() {
+ if (_soundOff)
+ return;
+
+ _reloadCFIEC = true;
+
+ Common::File fic;
+ if (!fic.open("mort.img"))
+ error("Missing file - mort.img");
+
+ fic.read(&_mem[0x3800 * 16 + 0], 500);
+ fic.read(&_mem[0x47a0 * 16 + 0], 123);
+ fic.close();
+
+ _soundManager.decodeMusic(&_mem[0x3800 * 16], &_mem[0x5000 * 16], 623);
+ _addFix = (float)((kTempoMusic - 8)) / 256;
+ _speechManager.cctable(_speechManager._tbi);
+
+ bool fin = false;
+ int k = 0;
+ do {
+ fin = keyPressed();
+ _soundManager.musyc(_speechManager._tbi, 9958, kTempoMusic);
+ ++k;
+ fin = fin | keyPressed() | (k >= 5);
+ } while (!fin);
+ while (keyPressed())
+ getChar();
+}
+
+/**
+ * Engine function - Show title screen
+ * @remarks Originally called 'suite'
+ */
+void MortevielleEngine::showTitleScreen() {
+ hirs();
+ handleDescriptionText(7, 2035);
+ _caff = 51;
+ _text.taffich();
+ testKeyboard();
+ if (_newGraphicalDevice != _currGraphicalDevice)
+ _currGraphicalDevice = _newGraphicalDevice;
+ hirs();
+ draw(kAdrDes, 0, 0);
+
+ Common::String cpr = "COPYRIGHT 1989 : LANKHOR";
+ _screenSurface.putxy(104 + 72 * _resolutionScaler, 185);
+ _screenSurface.drawString(cpr, 0);
+}
+
+/**
+ * Draw picture
+ * @remarks Originally called 'dessine'
+ */
+void MortevielleEngine::draw(int ad, int x, int y) {
+ _mouse.hideMouse();
+ setPal(_numpal);
+ pictout(ad, 0, x, y);
+ _mouse.showMouse();
+}
+
+/**
+ * Draw right frame
+ * @remarks Originally called 'dessine_rouleau'
+ */
+void MortevielleEngine::drawRightFrame() {
+ setPal(89);
+ if (_currGraphicalDevice == MODE_HERCULES) {
+ _mem[0x7000 * 16 + 14] = 15;
+ }
+ _mouse.hideMouse();
+ pictout(0x73a2, 0, 0, 0);
+ _mouse.showMouse();
+}
+
+/**
+ * Read the current system time
+ */
+int MortevielleEngine::readclock() {
+ TimeDate dateTime;
+ g_system->getTimeAndDate(dateTime);
+
+ int m = dateTime.tm_min * 60;
+ int h = dateTime.tm_hour * 3600;
+ return h + m + dateTime.tm_sec;
+}
+
+/**
+ * Engine function - Prepare room and hint string
+ * @remarks Originally called 'tinke'
+ */
+void MortevielleEngine::prepareRoom() {
+ int day, hour, minute;
+
+ _anyone = false;
+ updateHour(day, hour, minute);
+ if (day != _day) {
+ _day = day;
+ int i = 0;
+ do {
+ ++i;
+ if (_nbrepm[i] != 0)
+ --_nbrepm[i];
+ _nbrep[i] = 0;
+ } while (i != 8);
+ }
+ if ((hour > _hour) || ((hour == 0) && (_hour == 23))) {
+ _hour = hour;
+ _minute = 0;
+ drawClock();
+ int hintCount = 0;
+ for (int i = 1; i <= 10; ++i) {
+ if (_coreVar._pctHintFound[i] == '*')
+ ++hintCount;
+ }
+
+ Common::String pctStr;
+ if (hintCount == 10)
+ pctStr = "10";
+ else
+ pctStr = chr(hintCount + 48);
+
+ _hintPctMessage = "[1][";
+ _hintPctMessage += getEngineString(S_SHOULD_HAVE_NOTICED);
+ _hintPctMessage += pctStr;
+ _hintPctMessage += '0';
+ _hintPctMessage += getEngineString(S_NUMBER_OF_HINTS);
+ _hintPctMessage += "][";
+ _hintPctMessage += getEngineString(S_OK);
+ _hintPctMessage += ']';
+ }
+ if (minute > _minute) {
+ _minute = 30;
+ drawClock();
+ }
+ if (_mouse._pos.y < 12)
+ return;
+
+ if (!_blo) {
+ if ((hour == 12) || ((hour > 18) && (hour < 21)) || ((hour >= 0) && (hour < 7)))
+ _inGameHourDuration = kTime2;
+ else
+ _inGameHourDuration = kTime1;
+ if ((_coreVar._faithScore > 33) && (_coreVar._faithScore < 66))
+ _inGameHourDuration -= (_inGameHourDuration / 3);
+
+ if (_coreVar._faithScore > 65)
+ _inGameHourDuration -= ((_inGameHourDuration / 3) * 2);
+
+ int newHour = readclock();
+ if ((newHour - _currentDayHour) > _inGameHourDuration) {
+ bool activeMenu = _menu._menuActive;
+ _menu.eraseMenu();
+ _currentHourCount += ((newHour - _currentDayHour) / _inGameHourDuration);
+ _currentDayHour = newHour;
+ switch (_place) {
+ case GREEN_ROOM:
+ case DARKBLUE_ROOM:
+ setRandomPresenceGreenRoom(_coreVar._faithScore);
+ break;
+ case PURPLE_ROOM:
+ setRandomPresencePurpleRoom(_coreVar._faithScore);
+ break;
+ case BLUE_ROOM:
+ setRandomPresenceBlueRoom(_coreVar._faithScore);
+ break;
+ case RED_ROOM:
+ case GREEN_ROOM2:
+ setRandomPresenceRedRoom(_coreVar._faithScore);
+ break;
+ case ROOM9:
+ setRandomPresenceRoom9(_coreVar._faithScore);
+ break;
+ case DINING_ROOM:
+ setRandomPresenceDiningRoom(_coreVar._faithScore);
+ break;
+ case BUREAU:
+ setRandomPresenceBureau(_coreVar._faithScore);
+ break;
+ case KITCHEN:
+ setRandomPresenceKitchen(_coreVar._faithScore);
+ break;
+ case ATTIC:
+ case CELLAR:
+ setRandomPresenceAttic(_coreVar._faithScore);
+ break;
+ case LANDING:
+ case ROOM26:
+ setRandomPresenceLanding(_coreVar._faithScore);
+ break;
+ case CHAPEL:
+ setRandomPresenceChapel(_coreVar._faithScore);
+ break;
+ }
+ if ((_savedBitIndex != 0) && (_currBitIndex != 10))
+ _savedBitIndex = _currBitIndex;
+
+ if ((_savedBitIndex == 0) && (_currBitIndex > 0)) {
+ if ((_coreVar._currPlace == ATTIC) || (_coreVar._currPlace == CELLAR)) {
+ initCaveOrCellar();
+ } else if (_currBitIndex == 10) {
+ _currBitIndex = 0;
+ if (!_uptodatePresence) {
+ _uptodatePresence = true;
+ _startHour = readclock();
+ if (getRandomNumber(1, 5) < 5) {
+ clearVerbBar();
+ prepareScreenType2();
+ displayTextInVerbBar(getEngineString(S_HEAR_NOISE));
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _speechManager.startSpeech(1, rand, 1);
+ clearVerbBar();
+ }
+ }
+ }
+ }
+
+ if (activeMenu)
+ _menu.drawMenu();
+ }
+ }
+ _endHour = readclock();
+ if ((_uptodatePresence) && ((_endHour - _startHour) > 17)) {
+ getPresenceBitIndex(_place);
+ _uptodatePresence = false;
+ _startHour = 0;
+ if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
+ _anyone = true;
+ }
+}
+
+/**
+ * Engine function - Draw Clock
+ * @remarks Originally called 'pendule'
+ */
+void MortevielleEngine::drawClock() {
+ const int cv[2][12] = {
+ { 5, 8, 10, 8, 5, 0, -5, -8, -10, -8, -5, 0 },
+ { -5, -3, 0, 3, 5, 6, 5, 3, 0, -3, -5, -6 }
+ };
+ const int x = 580;
+ const int y = 123;
+ const int rg = 9;
+ int hourColor;
+
+ _mouse.hideMouse();
+
+ _screenSurface.drawRectangle(570, 118, 20, 10);
+ _screenSurface.drawRectangle(578, 114, 6, 18);
+ if ((_currGraphicalDevice == MODE_CGA) || (_currGraphicalDevice == MODE_HERCULES))
+ hourColor = 0;
+ else
+ hourColor = 1;
+
+ if (_minute == 0)
+ _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y - rg), hourColor);
+ else
+ _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)x >> 1) * _resolutionScaler, (y + rg), hourColor);
+
+ int hour12 = _hour;
+ if (hour12 > 12)
+ hour12 -= 12;
+ if (hour12 == 0)
+ hour12 = 12;
+
+ _screenSurface.drawLine(((uint)x >> 1) * _resolutionScaler, y, ((uint)(x + cv[0][hour12 - 1]) >> 1) * _resolutionScaler, y + cv[1][hour12 - 1], hourColor);
+ _mouse.showMouse();
+ _screenSurface.putxy(568, 154);
+
+ if (_hour > 11)
+ _screenSurface.drawString("PM ", 1);
+ else
+ _screenSurface.drawString("AM ", 1);
+
+ _screenSurface.putxy(550, 160);
+ if ((_day >= 0) && (_day <= 8)) {
+ Common::String tmp = getEngineString(S_DAY);
+ tmp.insertChar((char)(_day + 49), 0);
+ _screenSurface.drawString(tmp, 1);
+ }
+}
+
+void MortevielleEngine::palette(int v1) {
+ warning("TODO: palette");
+}
+
+/**
+ * Returns a substring of the given string
+ * @param s Source string
+ * @param idx Starting index (1 based)
+ * @param size Number of characters to return
+ */
+
+Common::String MortevielleEngine::copy(const Common::String &s, int idx, size_t size) {
+ // Copy the substring into a temporary buffer
+ char *tmp = new char[size + 1];
+ strncpy(tmp, s.c_str() + idx - 1, size);
+ tmp[size] = '\0';
+
+ Common::String result(tmp);
+ delete[] tmp;
+ return result;
+}
+
+void MortevielleEngine::hirs() {
+ // Note: The original used this to set the graphics mode and clear the screen, both at
+ // the start of the game, and whenever the screen need to be cleared. As such, this
+ // method is deprecated in favour of clearing the screen
+ debugC(1, kMortevielleCore, "TODO: hirs is deprecated in favour of ScreenSurface::clearScreen");
+
+ if (_currGraphicalDevice == MODE_TANDY) {
+ _screenSurface.fillRect(0, Common::Rect(0, 0, 639, 200));
+ _resolutionScaler = 1;
+ } else if (_currGraphicalDevice == MODE_CGA) {
+ palette(1);
+ _resolutionScaler = 1;
+ } else
+ _resolutionScaler = 2;
+
+ _screenSurface.clearScreen();
+}
+
+/**
+ * Init room : Cave or Cellar
+ * @remarks Originally called 'cavegre'
+ */
+void MortevielleEngine::initCaveOrCellar() {
+ _coreVar._faithScore += 2;
+ if (_coreVar._faithScore > 69)
+ _coreVar._faithScore += (_coreVar._faithScore / 10);
+ clearVerbBar();
+ prepareScreenType2();
+ displayTextInVerbBar(getEngineString(S_SOMEONE_ENTERS));
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _speechManager.startSpeech(2, rand, 1);
+
+ // The original was doing here a useless loop.
+ // It has been removed
+
+ clearVerbBar();
+ displayAloneText();
+}
+
+/**
+ * Display control menu string
+ * @remarks Originally called 'tctrm'
+ */
+void MortevielleEngine::displayControlMenu() {
+ handleDescriptionText(2, (3000 + _controlMenu));
+ _controlMenu = 0;
+}
+
+void MortevielleEngine::pictout(int seg, int dep, int x, int y) {
+ GfxSurface surface;
+ surface.decode(&_mem[seg * 16 + dep]);
+
+ if (_currGraphicalDevice == MODE_HERCULES) {
+ _mem[0x7000 * 16 + 2] = 0;
+ _mem[0x7000 * 16 + 32] = 15;
+ }
+
+ if ((_caff != 51) && (READ_LE_UINT16(&_mem[0x7000 * 16 + 0x4138]) > 0x100))
+ WRITE_LE_UINT16(&_mem[0x7000 * 16 + 0x4138], 0x100);
+
+ _screenSurface.drawPicture(surface, x, y);
+}
+
+void MortevielleEngine::adzon() {
+ Common::File f;
+
+ if (!f.open("don.mor"))
+ error("Missing file - don.mor");
+
+ f.read(_tabdon, 7 * 256);
+ f.close();
+
+ if (!f.open("bmor.mor"))
+ error("Missing file - bmor.mor");
+
+ f.read(&_tabdon[kFleche], 1 * 1916);
+ f.close();
+
+ if (!f.open("dec.mor"))
+ error("Missing file - dec.mor");
+
+ f.read(&_mem[0x73a2 * 16 + 0], 1 * 1664);
+ f.close();
+}
+
+/**
+ * Returns the offset within the compressed image data resource of the desired image
+ */
+int MortevielleEngine::animof(int ouf, int num) {
+ int nani = _mem[kAdrAni * 16 + 1];
+ int aux = num;
+ if (ouf != 1)
+ aux += nani;
+
+ int animof_result = (nani << 2) + 2 + READ_BE_UINT16(&_mem[kAdrAni * 16 + (aux << 1)]);
+
+ return animof_result;
+}
+
+/**
+ * Display text in description bar
+ * @remarks Originally called 'text1'
+ */
+void MortevielleEngine::displayTextInDescriptionBar(int x, int y, int nb, int mesgId) {
+ int co;
+
+ if (_resolutionScaler == 1)
+ co = 10;
+ else
+ co = 6;
+ Common::String tmpStr = getString(mesgId);
+ if ((y == 182) && ((int) tmpStr.size() * co > nb * 6))
+ y = 176;
+ _text.displayStr(tmpStr, x, y, nb, 20, _textColor);
+}
+
+/**
+ * Display description text
+ * @remarks Originally called 'repon'
+ */
+void MortevielleEngine::handleDescriptionText(int f, int mesgId) {
+ if ((mesgId > 499) && (mesgId < 563)) {
+ Common::String tmpStr = getString(mesgId - 501 + kInventoryStringIndex);
+
+ if ((int) tmpStr.size() > ((58 + (_resolutionScaler - 1) * 37) << 1))
+ _largestClearScreen = true;
+ else
+ _largestClearScreen = false;
+
+ clearDescriptionBar();
+ _text.displayStr(tmpStr, 8, 176, 85, 3, 5);
+ } else {
+ mapMessageId(mesgId);
+ switch (f) {
+ case 2:
+ case 8:
+ clearDescriptionBar();
+ prepareScreenType2();
+ displayTextInDescriptionBar(8, 182, 103, mesgId);
+ if ((mesgId == 68) || (mesgId == 69))
+ _coreVar._availableQuestion[40] = '*';
+ if ((mesgId == 104) && (_caff == CELLAR)) {
+ _coreVar._availableQuestion[36] = '*';
+ if (_coreVar._availableQuestion[39] == '*') {
+ _coreVar._pctHintFound[3] = '*';
+ _coreVar._availableQuestion[38] = '*';
+ }
+ }
+ break;
+ case 1:
+ case 6:
+ case 9: {
+ int i;
+ if ((f == 1) || (f == 6))
+ i = 4;
+ else
+ i = 5;
+
+ Common::String tmpStr = getString(mesgId);
+ _text.displayStr(tmpStr, 80, 40, 60, 25, i);
+
+ if (mesgId == 180)
+ _coreVar._pctHintFound[6] = '*';
+ else if (mesgId == 179)
+ _coreVar._pctHintFound[10] = '*';
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * Recompute message Id
+ * @remarks Originally called 'modif'
+ */
+void MortevielleEngine::mapMessageId(int &mesgId) {
+ if (mesgId == 26)
+ mesgId = 25;
+ else if ((mesgId > 29) && (mesgId < 36))
+ mesgId -= 4;
+ else if ((mesgId > 69) && (mesgId < 78))
+ mesgId -= 37;
+ else if ((mesgId > 99) && (mesgId < 194))
+ mesgId -= 59;
+ else if ((mesgId > 996) && (mesgId < 1000))
+ mesgId -= 862;
+ else if ((mesgId > 1500) && (mesgId < 1507))
+ mesgId -= 1363;
+ else if ((mesgId > 1507) && (mesgId < 1513))
+ mesgId -= 1364;
+ else if ((mesgId > 1999) && (mesgId < 2002))
+ mesgId -= 1851;
+ else if (mesgId == 2010)
+ mesgId = 151;
+ else if ((mesgId > 2011) && (mesgId < 2025))
+ mesgId -= 1860;
+ else if (mesgId == 2026)
+ mesgId = 165;
+ else if ((mesgId > 2029) && (mesgId < 2037))
+ mesgId -= 1864;
+ else if ((mesgId > 3000) && (mesgId < 3005))
+ mesgId -= 2828;
+ else if (mesgId == 4100)
+ mesgId = 177;
+ else if (mesgId == 4150)
+ mesgId = 178;
+ else if ((mesgId > 4151) && (mesgId < 4156))
+ mesgId -= 3973;
+ else if (mesgId == 4157)
+ mesgId = 183;
+ else if ((mesgId == 4160) || (mesgId == 4161))
+ mesgId -= 3976;
+}
+
+/**
+ * Initialize open objects array
+ * @remarks Originally called 'initouv'
+ */
+void MortevielleEngine::resetOpenObjects() {
+ for (int cx = 1; cx <= 7; ++cx)
+ _openObjects[cx] = 0;
+ _openObjCount = 0;
+}
+
+void MortevielleEngine::ecr2(Common::String text) {
+ // Some dead code was present in the original: removed
+ _screenSurface.putxy(8, 177);
+ int tlig = 59 + (_resolutionScaler - 1) * 36;
+
+ if ((int)text.size() < tlig)
+ _screenSurface.drawString(text, 5);
+ else if ((int)text.size() < (tlig << 1)) {
+ _screenSurface.putxy(8, 176);
+ _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
+ _screenSurface.putxy(8, 182);
+ _screenSurface.drawString(copy(text, tlig, tlig << 1), 5);
+ } else {
+ _largestClearScreen = true;
+ clearDescriptionBar();
+ _screenSurface.putxy(8, 176);
+ _screenSurface.drawString(copy(text, 1, (tlig - 1)), 5);
+ _screenSurface.putxy(8, 182);
+ _screenSurface.drawString(copy(text, tlig, ((tlig << 1) - 1)), 5);
+ _screenSurface.putxy(8, 190);
+ _screenSurface.drawString(copy(text, tlig << 1, tlig * 3), 5);
+ }
+}
+
+void MortevielleEngine::displayTextInVerbBar(Common::String text) {
+ clearVerbBar();
+ _screenSurface.putxy(8, 192);
+ _screenSurface.drawString(text, 5);
+}
+
+/**
+ * Display item in hand
+ * @remarks Originally called 'modobj'
+ */
+void MortevielleEngine::displayItemInHand(int objId) {
+ Common::String strp = Common::String(' ');
+
+ if (objId != 500)
+ strp = getString(objId - 501 + kInventoryStringIndex);
+
+ _menu.setText(_menu._inventoryMenu[8], strp);
+ _menu.disableMenuItem(_menu._inventoryMenu[8]);
+}
+
+/**
+ * Display empty hand
+ * @remarks Originally called 'maivid'
+ */
+void MortevielleEngine::displayEmptyHand() {
+ _coreVar._selectedObjectId = 0;
+ displayItemInHand(500);
+}
+
+/**
+ * Set a random presence: Leo or Max
+ * @remarks Originally called 'chlm'
+ */
+int MortevielleEngine::checkLeoMaxRandomPresence() {
+ int retval = getRandomNumber(1, 2);
+ if (retval == 2)
+ retval = 128;
+
+ return retval;
+}
+
+/**
+ * Reset room variables
+ * @remarks Originally called 'debloc'
+ */
+void MortevielleEngine::resetRoomVariables(int roomId) {
+ _num = 0;
+ _x = 0;
+ _y = 0;
+ if ((roomId != ROOM26) && (roomId != LANDING))
+ resetPresenceInRooms(roomId);
+ _savedBitIndex = _currBitIndex;
+}
+
+/**
+ * Compute presence stats
+ * @remarks Originally called 'ecfren'
+ */
+int MortevielleEngine::getPresenceStats(int &rand, int cf, int roomId) {
+ if (roomId == OWN_ROOM)
+ displayAloneText();
+ int retVal = -500;
+ rand = 0;
+ if ( ((roomId == GREEN_ROOM) && (!_roomPresenceLuc) && (!_roomPresenceIda))
+ || ((roomId == DARKBLUE_ROOM) && (!_roomPresenceGuy) && (!_roomPresenceEva)) )
+ retVal = getPresenceStatsGreenRoom();
+ if ((roomId == PURPLE_ROOM) && (!_purpleRoomPresenceLeo) && (!_room9PresenceLeo))
+ retVal = getPresenceStatsPurpleRoom();
+ if ( ((roomId == TOILETS) && (!_toiletsPresenceBobMax))
+ || ((roomId == BATHROOM) && (!_bathRoomPresenceBobMax)) )
+ retVal = getPresenceStatsToilets();
+ if ((roomId == BLUE_ROOM) && (!_roomPresenceMax))
+ retVal = getPresenceStatsBlueRoom();
+ if ( ((roomId == RED_ROOM) && (!_roomPresenceBob))
+ || ((roomId == GREEN_ROOM2) && (!_roomPresencePat)))
+ retVal = getPresenceStatsRedRoom();
+ if ((roomId == ROOM9) && (!_room9PresenceLeo) && (!_purpleRoomPresenceLeo))
+ retVal = 10;
+ if ( ((roomId == PURPLE_ROOM) && (_room9PresenceLeo))
+ || ((roomId == ROOM9) && (_purpleRoomPresenceLeo)))
+ retVal = -400;
+ if (retVal != -500) {
+ retVal += cf;
+ rand = getRandomNumber(1, 100);
+ }
+
+ return retVal;
+}
+
+/**
+ * Set presence flags
+ * @remarks Originally called 'becfren'
+ */
+void MortevielleEngine::setPresenceFlags(int roomId) {
+ if ((roomId == GREEN_ROOM) || (roomId == DARKBLUE_ROOM)) {
+ int rand = getRandomNumber(1, 2);
+ if (roomId == GREEN_ROOM) {
+ if (rand == 1)
+ _roomPresenceLuc = true;
+ else
+ _roomPresenceIda = true;
+ } else { // roomId == DARKBLUE_ROOM
+ if (rand == 1)
+ _roomPresenceGuy = true;
+ else
+ _roomPresenceEva = true;
+ }
+ } else if (roomId == PURPLE_ROOM)
+ _purpleRoomPresenceLeo = true;
+ else if (roomId == TOILETS)
+ _toiletsPresenceBobMax = true;
+ else if (roomId == BLUE_ROOM)
+ _roomPresenceMax = true;
+ else if (roomId == RED_ROOM)
+ _roomPresenceBob = true;
+ else if (roomId == BATHROOM)
+ _bathRoomPresenceBobMax = true;
+ else if (roomId == GREEN_ROOM2)
+ _roomPresencePat = true;
+ else if (roomId == ROOM9)
+ _room9PresenceLeo = true;
+}
+
+void MortevielleEngine::init_nbrepm() {
+ static const byte ipm[9] = { 0, 4, 5, 6, 7, 5, 6, 5, 8 };
+
+ for (int idx = 0; idx < 9; ++idx)
+ _nbrepm[idx] = ipm[idx];
+}
+
+void MortevielleEngine::phaz(int &rand, int &p, int cf) {
+ p += cf;
+ rand = getRandomNumber(1, 100);
+}
+
+/**
+ * Get Presence
+ * @remarks Originally called 't11'
+ */
+int MortevielleEngine::getPresence(int roomId) {
+ int retVal = 0;
+ int rand;
+
+ int p = getPresenceStats(rand, _coreVar._faithScore, roomId);
+ _place = roomId;
+ if ((roomId > OWN_ROOM) && (roomId < DINING_ROOM)) {
+ if (p != -500) {
+ if (rand > p) {
+ displayAloneText();
+ retVal = 0;
+ } else {
+ setPresenceFlags(_place);
+ retVal = getPresenceBitIndex(_place);
+ }
+ } else
+ retVal = getPresenceBitIndex(_place);
+ }
+
+ if (roomId > ROOM9) {
+ if ((roomId > LANDING) && (roomId != CHAPEL) && (roomId != ROOM26))
+ displayAloneText();
+ else {
+ int h = 0;
+ if (roomId == DINING_ROOM)
+ p = getPresenceStatsDiningRoom(h);
+ else if (roomId == BUREAU)
+ p = getPresenceStatsBureau(h);
+ else if (roomId == KITCHEN)
+ p = getPresenceStatsKitchen();
+ else if ((roomId == ATTIC) || (roomId == CELLAR))
+ p = getPresenceStatsAttic();
+ else if ((roomId == LANDING) || (roomId == ROOM26))
+ p = getPresenceStatsLanding();
+ else if (roomId == CHAPEL)
+ p = getPresenceStatsChapel(h);
+ p += _coreVar._faithScore;
+ rand = getRandomNumber(1, 100);
+ if (rand > p) {
+ displayAloneText();
+ retVal = 0;
+ } else {
+ if (roomId == DINING_ROOM)
+ p = setPresenceDiningRoom(h);
+ else if (roomId == BUREAU)
+ p = setPresenceBureau(h);
+ else if ((roomId == KITCHEN) || (roomId == ATTIC) || (roomId == CELLAR))
+ p = setPresenceKitchen();
+ else if ((roomId == LANDING) || (roomId == ROOM26))
+ p = setPresenceLanding();
+ else if (roomId == CHAPEL)
+ p = setPresenceChapel(h);
+ retVal = p;
+ }
+ }
+ }
+
+ return retVal;
+}
+
+void MortevielleEngine::writetp(Common::String s, int t) {
+ if (_resolutionScaler == 2)
+ _screenSurface.drawString(s, t);
+ else
+ _screenSurface.drawString(copy(s, 1, 25), t);
+}
+
+void MortevielleEngine::aniof(int ouf, int num) {
+ if ((_caff == BATHROOM) && ((num == 4) || (num == 5)))
+ return;
+
+ if ((_caff == DINING_ROOM) && (num == 7))
+ num = 6;
+ else if (_caff == KITCHEN) {
+ if (num == 3)
+ num = 4;
+ else if (num == 4)
+ num = 3;
+ }
+
+ int ad = kAdrAni;
+ int offset = animof(ouf, num);
+
+ GfxSurface surface;
+ surface.decode(&_mem[ad * 16 + offset]);
+ _screenSurface.drawPicture(surface, 0, 12);
+
+ prepareScreenType1();
+}
+
+/**
+ * Draw Picture
+ * @remarks Originally called 'dessin'
+ */
+void MortevielleEngine::drawPicture() {
+ clearUpperLeftPart();
+ if (_caff > 99) {
+ draw(kAdrDes, 60, 33);
+ _screenSurface.drawBox(118, 32, 291, 121, 15); // Medium box
+ } else if (_caff > 69) {
+ draw(kAdrDes, 112, 48); // Heads
+ _screenSurface.drawBox(222, 47, 155, 91, 15);
+ } else {
+ draw(kAdrDes, 0, 12);
+ prepareScreenType1();
+ if ((_caff < 30) || (_caff > 32)) {
+ for (int cx = 1; cx <= 6; ++cx) {
+ if (_openObjects[cx] != 0)
+ aniof(1, _openObjects[cx]);
+ }
+
+ if (_caff == ATTIC) {
+ if (_coreVar._atticBallHoleObjectId == 141)
+ aniof(1, 7);
+
+ if (_coreVar._atticRodHoleObjectId == 159)
+ aniof(1, 6);
+ } else if ((_caff == CELLAR) && (_coreVar._cellarObjectId == 151))
+ aniof(1, 2);
+ else if ((_caff == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143))
+ aniof(1, 1);
+ else if ((_caff == WELL) && (_coreVar._wellObjectId != 0))
+ aniof(1, 1);
+ }
+
+ if (_caff < ROOM26)
+ startMusicOrSpeech(1);
+ }
+}
+
+void MortevielleEngine::drawPictureWithText() {
+ _text.taffich();
+ drawPicture();
+ _destinationOk = false;
+}
+
+/**
+ * Engine function - Place
+ * @remarks Originally called 'tkey1'
+ */
+void MortevielleEngine::testKey(bool d) {
+ bool quest = false;
+ int x, y;
+ bool click;
+
+ _mouse.hideMouse();
+ fenat('K');
+
+ // Wait for release from any key or mouse button
+ while (keyPressed())
+ _key = testou();
+
+ do {
+ _mouse.getMousePosition(x, y, click);
+ keyPressed();
+ } while (click);
+
+ // Event loop
+ do {
+ if (d)
+ prepareRoom();
+ quest = keyPressed();
+ _mouse.getMousePosition(x, y, click);
+ if (shouldQuit())
+ return;
+ } while (!(quest || (click) || (d && _anyone)));
+ if (quest)
+ testou();
+ setMouseClick(false);
+ _mouse.showMouse();
+}
+
+void MortevielleEngine::tlu(int af, int ob) {
+ _caff = 32;
+ drawPictureWithText();
+ handleDescriptionText(6, ob + 4000);
+ handleDescriptionText(2, 999);
+ testKey(true);
+ _caff = af;
+ _msg[3] = OPCODE_NONE;
+ _crep = 998;
+}
+
+void MortevielleEngine::affrep() {
+ _caff = _coreVar._currPlace;
+ _crep = _coreVar._currPlace;
+}
+
+/**
+ * Exit room
+ * @remarks Originally called 'tsort'
+ */
+void MortevielleEngine::exitRoom() {
+ if ((_openObjCount > 0) && (_coreVar._currPlace != OWN_ROOM)) {
+ if (_coreVar._faithScore < 50)
+ _coreVar._faithScore += 2;
+ else
+ _coreVar._faithScore += (_coreVar._faithScore / 10);
+ }
+
+ resetOpenObjects();
+
+ _roomDoorId = OWN_ROOM;
+ _mchai = 0;
+ resetRoomVariables(_coreVar._currPlace);
+}
+
+/**
+ * get 'read' description
+ * @remarks Originally called 'st4'
+ */
+void MortevielleEngine::getReadDescription(int objId) {
+ _crep = 997;
+
+ switch (objId) {
+ case 114 :
+ _crep = 109;
+ break;
+ case 110 :
+ _crep = 107;
+ break;
+ case 158 :
+ _crep = 113;
+ break;
+ case 152:
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 150:
+ case 100:
+ case 157:
+ case 160:
+ case 161 :
+ tlu(_caff, objId);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * get 'search' description
+ * @remarks Originally called 'st7'
+ */
+void MortevielleEngine::getSearchDescription(int objId) {
+ switch (objId) {
+ case 116:
+ case 144:
+ _crep = 104;
+ break;
+ case 126:
+ case 111:
+ _crep = 108;
+ break;
+ case 132:
+ _crep = 111;
+ break;
+ case 142:
+ _crep = 112;
+ break;
+ default:
+ _crep = 183;
+ getReadDescription(objId);
+ }
+}
+
+void MortevielleEngine::mennor() {
+ _menu.menuUp(_msg[3]);
+}
+
+void MortevielleEngine::premtet() {
+ draw(kAdrDes, 10, 80);
+ _screenSurface.drawBox(18, 79, 155, 91, 15);
+}
+
+void MortevielleEngine::ajchai() {
+ int cy = kAcha + ((_mchai - 1) * 10) - 1;
+ int cx = 0;
+ do {
+ ++cx;
+ } while ((cx <= 9) && (_tabdon[cy + cx] != 0));
+
+ if (_tabdon[cy + cx] == 0)
+ _tabdon[cy + cx] = _coreVar._selectedObjectId;
+ else
+ _crep = 192;
+}
+
+/**
+ * Check if inventory is full and, if not, add object in it.
+ * @remarks Originally called 'ajjer'
+ */
+void MortevielleEngine::addObjectToInventory(int objectId) {
+ int i = 0;
+ do {
+ ++i;
+ } while ((i <= 5) && (_coreVar._inventory[i] != 0));
+
+ if (_coreVar._inventory[i] == 0) {
+ _coreVar._inventory[i] = objectId;
+ _menu.setInventoryText();
+ } else
+ // Inventory is full
+ _crep = 139;
+}
+
+/**
+ * Interact with NPC
+ * @remarks Originally called 'quelquun'
+ */
+void MortevielleEngine::interactNPC() {
+ if (_menu._menuDisplayed)
+ _menu.eraseMenu();
+
+ endSearch();
+ _crep = 997;
+L1:
+ if (!_hiddenHero) {
+ if (_crep == 997)
+ _crep = 138;
+ handleDescriptionText(2, _crep);
+ if (_crep == 138)
+ _speechManager.startSpeech(5, 2, 1);
+ else
+ _speechManager.startSpeech(4, 4, 1);
+
+ if (_openObjCount == 0)
+ _coreVar._faithScore += 2;
+ else if (_coreVar._faithScore < 50)
+ _coreVar._faithScore += 4;
+ else
+ _coreVar._faithScore += 3 * (_coreVar._faithScore / 10);
+ exitRoom();
+ _menu.setDestinationText(LANDING);
+ int cx = convertBitIndexToCharacterIndex(_currBitIndex);
+ _caff = 69 + cx;
+ _crep = _caff;
+ _msg[3] = MENU_DISCUSS;
+ _msg[4] = _menu._discussMenu[cx];
+ _syn = true;
+ _col = true;
+ } else {
+ if (getRandomNumber(1, 3) == 2) {
+ _hiddenHero = false;
+ _crep = 137;
+ goto L1;
+ } else {
+ handleDescriptionText(2, 136);
+ int rand = (getRandomNumber(0, 4)) - 2;
+ _speechManager.startSpeech(3, rand, 1);
+ clearDescriptionBar();
+ displayAloneText();
+ resetRoomVariables(MANOR_FRONT);
+ affrep();
+ }
+ }
+ if (_menu._menuDisplayed)
+ _menu.drawMenu();
+}
+
+void MortevielleEngine::tsuiv() {
+ int tbcl;
+ int cy = kAcha + ((_mchai - 1) * 10) - 1;
+ int cx = 0;
+ do {
+ ++cx;
+ ++_searchCount;
+ int cl = cy + _searchCount;
+ tbcl = _tabdon[cl];
+ } while ((tbcl == 0) && (_searchCount <= 9));
+
+ if ((tbcl != 0) && (_searchCount < 11)) {
+ _caff = tbcl;
+ _crep = _caff + 400;
+ if (_currBitIndex != 0)
+ _coreVar._faithScore += 2;
+ } else {
+ affrep();
+ endSearch();
+ if (cx > 9)
+ _crep = 131;
+ }
+}
+
+void MortevielleEngine::tfleche() {
+ bool qust;
+ char touch;
+
+ if (_num == 9999)
+ return;
+
+ fenat(chr(152));
+ bool inRect = false;
+ do {
+ touch = '\0';
+
+ do {
+ _mouse.moveMouse(qust, touch);
+ if (shouldQuit())
+ return;
+
+ if (getMouseClick())
+ inRect = (_mouse._pos.x < 256 * _resolutionScaler) && (_mouse._pos.y < 176) && (_mouse._pos.y > 12);
+ prepareRoom();
+ } while (!(qust || inRect || _anyone));
+
+ if (qust && (touch == '\103'))
+ _dialogManager.show(_hintPctMessage, 1);
+ } while (!((touch == '\73') || ((touch == '\104') && (_x != 0) && (_y != 0)) || (_anyone) || (inRect)));
+
+ if (touch == '\73')
+ _keyPressedEsc = true;
+
+ if (inRect) {
+ _x = _mouse._pos.x;
+ _y = _mouse._pos.y;
+ }
+}
+
+/**
+ * Set coordinates
+ * @remarks Originally called 'tcoord'
+ */
+void MortevielleEngine::setCoordinates(int sx) {
+ int sy, ix, iy;
+ int ib;
+
+
+ _num = 0;
+ _crep = 999;
+ int a = 0;
+ int atdon = kAmzon + 3;
+ int cy = 0;
+ while (cy < _caff) {
+ a += _tabdon[atdon];
+ atdon += 4;
+ ++cy;
+ }
+
+ if (_tabdon[atdon] == 0) {
+ _crep = 997;
+ return;
+ }
+
+ a += kFleche;
+ int cb = 0;
+ for (cy = 0; cy <= (sx - 2); ++cy) {
+ ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
+ cb += (ib * 4) + 2;
+ }
+ ib = (_tabdon[a + cb] << 8) + _tabdon[(a + cb + 1)];
+ if (ib == 0) {
+ _crep = 997;
+ return;
+ }
+
+ cy = 1;
+ do {
+ cb += 2;
+ sx = _tabdon[a + cb] * _resolutionScaler;
+ sy = _tabdon[(a + cb + 1)];
+ cb += 2;
+ ix = _tabdon[a + cb] * _resolutionScaler;
+ iy = _tabdon[(a + cb + 1)];
+ ++cy;
+ } while (!(((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) || (cy > ib)));
+
+ if ((_x >= sx) && (_x <= ix) && (_y >= sy) && (_y <= iy)) {
+ _num = cy - 1;
+ return;
+ }
+
+ _crep = 997;
+}
+
+void MortevielleEngine::treg(int objId) {
+ int mdes = _caff;
+ _caff = objId;
+
+ if (((_caff > 29) && (_caff < 33)) || (_caff == 144) || (_caff == 147) || (_caff == 149) || (_msg[4] == OPCODE_SLOOK)) {
+ drawPictureWithText();
+ if ((_caff > 29) && (_caff < 33))
+ handleDescriptionText(2, _caff);
+ else
+ handleDescriptionText(2, _caff + 400);
+ testKey(true);
+ _caff = mdes;
+ _msg[3] = 0;
+ _crep = 998;
+ } else {
+ _obpart = true;
+ _crep = _caff + 400;
+ _menu.setSearchMenu();
+ }
+}
+
+/**
+ * Engine function - Put in hand
+ * @remarks Originally called 'avpoing'
+ */
+void MortevielleEngine::putInHand(int &objId) {
+ _crep = 999;
+ if (_coreVar._selectedObjectId != 0)
+ addObjectToInventory(_coreVar._selectedObjectId);
+
+ // If inventory wasn't full
+ if (_crep != 139) {
+ displayItemInHand(objId + 400);
+ _coreVar._selectedObjectId = objId;
+ objId = 0;
+ }
+}
+
+void MortevielleEngine::rechai(int &ch) {
+ int tmpPlace = _coreVar._currPlace;
+
+ if (_coreVar._currPlace == CRYPT)
+ tmpPlace = CELLAR;
+ ch = _tabdon[kAchai + (tmpPlace * 7) + _num - 1];
+}
+
+/**
+ * Check before leaving the secret passage
+ * @remarks Originally called 't23coul'
+ */
+int MortevielleEngine::checkLeaveSecretPassage() {
+ if (!checkInventory(143)) {
+ _crep = 1512;
+ loseGame();
+ }
+
+ return CELLAR;
+}
+
+void MortevielleEngine::fenat(char ans) {
+ int coul;
+
+ _mouse.hideMouse();
+ if (_currGraphicalDevice == MODE_CGA)
+ coul = 2;
+ else if (_currGraphicalDevice == MODE_HERCULES)
+ coul = 1;
+ else
+ coul = 12;
+
+ _screenSurface.writeCharacter(Common::Point(306, 193), ord(ans), coul);
+ _screenSurface.drawBox(300, 191, 16, 8, 15);
+ _mouse.showMouse();
+}
+
+/**
+ * Test Keyboard
+ * @remarks Originally called 'teskbd'
+ */
+void MortevielleEngine::testKeyboard() {
+ if (keyPressed())
+ testou();
+}
+
+int MortevielleEngine::testou() {
+ char ch = getChar();
+
+ switch (ch) {
+ case '\23' :
+ _soundOff = !_soundOff;
+ break;
+ case '\26' :
+ if ((_x26KeyCount == 1) || (_x26KeyCount == 2)) {
+ decodeNumber(&_cfiecBuffer[161 * 16], (_cfiecBufferSize - (161 * 16)) / 64);
+ ++_x26KeyCount;
+
+ return 61;
+ }
+ break;
+ case '\33' :
+ if (keyPressed())
+ ch = getChar();
+ break;
+ default:
+ break;
+ }
+
+ return ord(ch);
+}
+
+void MortevielleEngine::sauvecr(int y, int dy) {
+// _mouse.hideMouse();
+// _mouse.showMouse();
+}
+
+void MortevielleEngine::charecr(int y, int dy) {
+// _mouse.hideMouse();
+// _mouse.showMouse();
+}
+
+} // End of namespace Mortevielle