mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-27 12:16:59 +00:00
523 lines
14 KiB
C++
523 lines
14 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 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
|
|
*/
|
|
|
|
#ifndef MORTEVIELLE_MORTEVIELLE_H
|
|
#define MORTEVIELLE_MORTEVIELLE_H
|
|
|
|
#include "common/events.h"
|
|
#include "common/file.h"
|
|
#include "common/random.h"
|
|
#include "common/rect.h"
|
|
#include "common/stack.h"
|
|
#include "engines/advancedDetector.h"
|
|
#include "engines/engine.h"
|
|
#include "common/error.h"
|
|
#include "graphics/surface.h"
|
|
#include "mortevielle/debugger.h"
|
|
#include "mortevielle/dialogs.h"
|
|
#include "mortevielle/graphics.h"
|
|
#include "mortevielle/menu.h"
|
|
#include "mortevielle/mouse.h"
|
|
#include "mortevielle/saveload.h"
|
|
#include "mortevielle/sound.h"
|
|
#include "mortevielle/speech.h"
|
|
#include "mortevielle/outtext.h"
|
|
|
|
namespace Mortevielle {
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*------------------- MEMORY MAP ------------------------*/
|
|
/*---------------------------------------------------------------------------*/
|
|
/* The following is a list of physical addresses in memory currently used
|
|
* by the game.
|
|
*
|
|
* Address
|
|
* -------
|
|
* 5000:0 - Music data
|
|
* 6000:0 - Decompressed current image
|
|
* 7000:0+ - Compressed images
|
|
* 7000:2 - 16 words representing palette map
|
|
* 7000:4138 - width, height, x/y offset of decoded image
|
|
*/
|
|
const int kAdrMusic = 0x5000;
|
|
|
|
// Debug channels
|
|
enum {
|
|
kMortevielleCore = 1 << 0,
|
|
kMortevielleGraphics = 1 << 1
|
|
};
|
|
|
|
// Game languages
|
|
enum {
|
|
MORTDAT_LANG_FRENCH = 0,
|
|
MORTDAT_LANG_ENGLISH = 1,
|
|
MORTDAT_LANG_GERMAN = 2
|
|
};
|
|
|
|
// Static string list
|
|
enum {
|
|
S_YES_NO = 0, S_GO_TO = 1, S_SOMEONE_ENTERS = 2, S_COOL = 3, S_LOURDE = 4,
|
|
S_MALSAINE = 5, S_IDEM = 6, S_YOU = 7, S_ARE = 8, S_ALONE = 9,
|
|
S_HEAR_NOISE = 10, S_SHOULD_HAVE_NOTICED = 11, S_NUMBER_OF_HINTS = 12,
|
|
S_WANT_TO_WAKE_UP = 13, S_OKAY = 14, S_SAVE_LOAD = 15, S_RESTART = 18, S_F3 = 19,
|
|
S_F8 = 20, S_HIDE_SELF = 21, S_TAKE = 22, S_PROBE = 23, S_RAISE = 24, S_SUITE = 25,
|
|
S_STOP = 26, S_USE_DEP_MENU = 27, S_LIFT = 28, S_READ = 29,
|
|
S_LOOK = 30, S_SEARCH = 31, S_OPEN = 32, S_PUT = 33, S_TURN = 34, S_TIE = 35, S_CLOSE = 36,
|
|
S_HIT = 37, S_POSE = 38, S_SMASH = 39,
|
|
|
|
S_SMELL = 40, S_SCRATCH = 41, S_PROBE2 = 42, S_BEFORE_USE_DEP_MENU = 43, S_DAY = 44
|
|
};
|
|
|
|
enum DataType {
|
|
kStaticStrings = 0,
|
|
kGameStrings = 1
|
|
};
|
|
|
|
#define SCREEN_WIDTH 640
|
|
#define SCREEN_HEIGHT 400
|
|
#define SCREEN_ORIG_HEIGHT 200
|
|
#define MORT_DAT_REQUIRED_VERSION 1
|
|
#define MORT_DAT "mort.dat"
|
|
#define GAME_FRAME_DELAY (1000 / 50)
|
|
|
|
const int kTime1 = 410;
|
|
const int kTime2 = 250;
|
|
|
|
const int kAcha = 492;
|
|
const int kFleche = 1758;
|
|
|
|
const int kAsoul = 154;
|
|
const int kAouvr = 282;
|
|
const int kAchai = 387;
|
|
const int kArcf = 1272;
|
|
const int kArep = 1314;
|
|
const int kAmzon = 1650;
|
|
const int kArega = 0;
|
|
|
|
const int kMaxDialogIndex = 9000;
|
|
const int kMaxDialogHint = 600;
|
|
|
|
const int kDescriptionStringIndex = 0; // Unused
|
|
const int kInventoryStringIndex = 186;
|
|
const int kQuestionStringIndex = 247;
|
|
const int kDialogStringIndex = 292;
|
|
const int kMenuPlaceStringIndex = 435;
|
|
const int kMenuActionStringIndex = 476;
|
|
const int kMenuSelfStringIndex = 497;
|
|
const int kMenuSayStringIndex = 502;
|
|
const int kMaxPatt = 20;
|
|
|
|
/*
|
|
9 "A glance at the forbidden$",
|
|
18 "It's already open$",
|
|
26 "A photograph$"
|
|
*/
|
|
enum Places {
|
|
OWN_ROOM = 0, GREEN_ROOM = 1, PURPLE_ROOM = 2, TOILETS = 3, DARKBLUE_ROOM = 4,
|
|
BLUE_ROOM = 5, RED_ROOM = 6, BATHROOM = 7, GREEN_ROOM2 = 8, ROOM9 = 9,
|
|
DINING_ROOM = 10, BUREAU = 11, KITCHEN = 12, ATTIC = 13, CELLAR = 14,
|
|
LANDING = 15, CRYPT = 16, SECRET_PASSAGE = 17, ROOM18 = 18, MOUNTAIN = 19,
|
|
CHAPEL = 20, MANOR_FRONT = 21, MANOR_BACK = 22, INSIDE_WELL = 23, WELL = 24,
|
|
DOOR = 25, ROOM26 = 26, COAT_ARMS = 27
|
|
};
|
|
|
|
enum GraphicModes { MODE_AMSTRAD1512 = 0, MODE_CGA = 1, MODE_EGA = 2, MODE_HERCULES = 3, MODE_TANDY = 4 };
|
|
|
|
struct nhom {
|
|
byte _id; /* number between 0 and 32 */
|
|
byte _hom[4];
|
|
};
|
|
|
|
struct CgaPalette {
|
|
byte _p;
|
|
nhom _a[16];
|
|
};
|
|
|
|
struct Pattern {
|
|
byte _tay, _tax;
|
|
byte _des[kMaxPatt + 1][kMaxPatt + 1];
|
|
};
|
|
|
|
struct SaveStruct {
|
|
int _faithScore;
|
|
byte _pctHintFound[11];
|
|
byte _availableQuestion[43];
|
|
byte _inventory[31];
|
|
int _currPlace;
|
|
int _atticBallHoleObjectId;
|
|
int _atticRodHoleObjectId;
|
|
int _cellarObjectId;
|
|
int _secretPassageObjectId;
|
|
int _wellObjectId;
|
|
int _selectedObjectId;
|
|
int _purpleRoomObjectId;
|
|
int _cryptObjectId;
|
|
bool _alreadyEnteredManor;
|
|
byte _fullHour;
|
|
};
|
|
|
|
struct Hint {
|
|
int _hintId;
|
|
byte _point;
|
|
};
|
|
|
|
class MortevielleEngine : public Engine {
|
|
private:
|
|
const ADGameDescription *_gameDescription;
|
|
Common::Stack<int> _keypresses;
|
|
uint32 _lastGameFrame;
|
|
Common::Point _mousePos;
|
|
Common::StringArray _engineStrings;
|
|
Common::StringArray _gameStrings;
|
|
|
|
Pattern _patternArr[15];
|
|
int _menuOpcode;
|
|
|
|
bool _mouseClick;
|
|
bool _inMainGameLoop; // Flag when the main game loop is active
|
|
bool _quitGame; // Quit game flag. Originally called 'arret'
|
|
bool _endGame; // End game flag. Originally called 'solu'
|
|
bool _loseGame; // Lose game flag. Originally called 'perdu'
|
|
bool _txxFileFl; // Flag used to determine if texts are from the original files or from a DAT file
|
|
bool _roomPresenceLuc;
|
|
bool _roomPresenceIda;
|
|
bool _purpleRoomPresenceLeo;
|
|
bool _roomPresenceGuy;
|
|
bool _roomPresenceEva;
|
|
bool _roomPresenceMax;
|
|
bool _roomPresenceBob;
|
|
bool _roomPresencePat;
|
|
bool _toiletsPresenceBobMax;
|
|
bool _bathRoomPresenceBobMax;
|
|
bool _room9PresenceLeo;
|
|
bool _hiddenHero;
|
|
bool _heroSearching;
|
|
bool _keyPressedEsc;
|
|
bool _reloadCFIEC;
|
|
bool _col;
|
|
bool _syn;
|
|
bool _obpart;
|
|
bool _anyone;
|
|
bool _uptodatePresence;
|
|
|
|
int _textColor;
|
|
int _place;
|
|
int _manorDistance;
|
|
int _currBitIndex;
|
|
int _currDay;
|
|
int _currHour;
|
|
int _currHalfHour;
|
|
int _day;
|
|
int _hour;
|
|
int _minute;
|
|
int _mchai;
|
|
int _controlMenu;
|
|
int _startHour;
|
|
int _endHour;
|
|
Common::Point _stdPal[91][17];
|
|
CgaPalette _cgaPal[91];
|
|
|
|
int _x26KeyCount;
|
|
int _roomDoorId;
|
|
int _openObjCount;
|
|
int _takeObjCount;
|
|
int _num;
|
|
int _searchCount;
|
|
bool _introSpeechPlayed;
|
|
int _inGameHourDuration;
|
|
int _x;
|
|
int _y;
|
|
int _currentHourCount;
|
|
int _currentDayHour;
|
|
|
|
Common::String _hintPctMessage;
|
|
byte *_cfiecBuffer;
|
|
int _cfiecBufferSize;
|
|
int _openObjects[7];
|
|
uint16 _dialogIndexArray[kMaxDialogIndex + 1];
|
|
Hint _dialogHintArray[kMaxDialogHint + 1];
|
|
|
|
Common::ErrorCode initialize();
|
|
Common::ErrorCode loadMortDat();
|
|
void readStaticStrings(Common::File &f, int dataSize, DataType dataType);
|
|
void loadFont(Common::File &f);
|
|
bool handleEvents();
|
|
void addKeypress(Common::Event &evt);
|
|
void initMouse();
|
|
void showIntroduction();
|
|
void mainGame();
|
|
void playGame();
|
|
void handleAction();
|
|
void displayCGAPattern(int n, Pattern p, nhom *pal);
|
|
void loadPalette();
|
|
void loadTexts();
|
|
void loadBRUIT5();
|
|
void loadCFIEC();
|
|
void loadCFIPH();
|
|
void showTitleScreen();
|
|
int readclock();
|
|
void palette(int v1);
|
|
int checkLeoMaxRandomPresence();
|
|
void interactNPC();
|
|
void initCaveOrCellar();
|
|
void displayControlMenu();
|
|
void displayItemInHand(int objId);
|
|
void resetRoomVariables(int roomId);
|
|
int getPresenceStats(int &rand, int faithScore, int roomId);
|
|
void setPresenceFlags(int roomId);
|
|
void testKey(bool d);
|
|
void exitRoom();
|
|
void getReadDescription(int objId);
|
|
void getSearchDescription(int objId);
|
|
int checkLeaveSecretPassage();
|
|
void changeGraphicalDevice(int newDevice);
|
|
void startDialog(int16 rep);
|
|
void endSearch();
|
|
int convertCharacterIndexToBitIndex(int characterIndex);
|
|
int convertBitIndexToCharacterIndex(int bitIndex);
|
|
void clearUpperLeftPart();
|
|
void clearDescriptionBar();
|
|
void clearVerbBar();
|
|
void clearUpperRightPart();
|
|
int getRandomNumber(int minval, int maxval);
|
|
void showMoveMenuAlert();
|
|
void showConfigScreen();
|
|
void decodeNumber(byte *pStart, int count);
|
|
void resetVariables();
|
|
void music();
|
|
void drawRightFrame();
|
|
void prepareRoom();
|
|
void drawClock();
|
|
void checkManorDistance();
|
|
void gotoManorFront();
|
|
void gotoManorBack();
|
|
void gotoDiningRoom();
|
|
bool checkInventory(int objectId);
|
|
void loseGame();
|
|
void floodedInWell();
|
|
void displayDiningRoom();
|
|
void startMusicOrSpeech(int so);
|
|
void setTextColor(int col);
|
|
void prepareScreenType1();
|
|
void prepareScreenType2();
|
|
void prepareScreenType3();
|
|
void updateHour(int &day, int &hour, int &minute);
|
|
void getKnockAnswer();
|
|
int getPresenceStatsGreenRoom();
|
|
int getPresenceStatsPurpleRoom();
|
|
int getPresenceStatsToilets();
|
|
int getPresenceStatsBlueRoom();
|
|
int getPresenceStatsRedRoom();
|
|
int getPresenceStatsDiningRoom(int &hour);
|
|
int getPresenceStatsBureau(int &hour);
|
|
int getPresenceStatsKitchen();
|
|
int getPresenceStatsAttic();
|
|
int getPresenceStatsLanding();
|
|
int getPresenceStatsChapel(int &hour);
|
|
int getPresenceBitIndex(int roomId);
|
|
void setPresenceGreenRoom(int roomId);
|
|
void setPresencePurpleRoom();
|
|
void setPresenceBlueRoom();
|
|
void setPresenceRedRoom(int roomId);
|
|
int setPresenceDiningRoom(int hour);
|
|
int setPresenceBureau(int hour);
|
|
int setPresenceKitchen();
|
|
int setPresenceLanding();
|
|
int setPresenceChapel(int hour);
|
|
void setRandomPresenceGreenRoom(int faithScore);
|
|
void setRandomPresencePurpleRoom(int faithScore);
|
|
void setRandomPresenceBlueRoom(int faithScore);
|
|
void setRandomPresenceRedRoom(int faithScore);
|
|
void setRandomPresenceRoom9(int faithScore);
|
|
void setRandomPresenceDiningRoom(int faithScore);
|
|
void setRandomPresenceBureau(int faithScore);
|
|
void setRandomPresenceKitchen(int faithScore);
|
|
void setRandomPresenceAttic(int faithScore);
|
|
void setRandomPresenceLanding(int faithScore);
|
|
void setRandomPresenceChapel(int faithScore);
|
|
void loadPlaces();
|
|
void resetPresenceInRooms(int roomId);
|
|
void showPeoplePresent(int bitIndex);
|
|
int selectCharacters(int min, int max);
|
|
void fctMove();
|
|
void fctTake();
|
|
void fctInventoryTake();
|
|
void fctLift();
|
|
void fctRead();
|
|
void fctSelfRead();
|
|
void fctLook();
|
|
void fctSelftLook();
|
|
void fctSearch();
|
|
void fctSelfSearch();
|
|
void fctOpen();
|
|
void fctPlace();
|
|
void fctTurn();
|
|
void fctSelfHide();
|
|
void fctAttach();
|
|
void fctClose();
|
|
void fctKnock();
|
|
void fctSelfPut();
|
|
void fctListen();
|
|
void fctEat();
|
|
void fctEnter();
|
|
void fctSleep();
|
|
void fctForce();
|
|
void fctLeave();
|
|
void fctWait();
|
|
void fctSound();
|
|
void fctDiscuss();
|
|
void fctSmell();
|
|
void fctScratch();
|
|
void endGame();
|
|
void askRestart();
|
|
void handleOpcode();
|
|
void prepareDisplayText();
|
|
bool decryptNextChar(char &c, int &idx, byte &pt);
|
|
void displayStatusArrow();
|
|
void displayStatusInDescriptionBar(char stat);
|
|
void displayQuestionText(Common::String s, int cmd);
|
|
void displayTextInDescriptionBar(int x, int y, int nb, int mesgId);
|
|
void displayTextInVerbBar(Common::String text);
|
|
void mapMessageId(int &mesgId);
|
|
void resetOpenObjects();
|
|
void setCoordinates(int sx);
|
|
void drawPicture();
|
|
void drawPictureWithText();
|
|
void addObjectToInventory(int objectId);
|
|
void putInHand(int &objId);
|
|
void initMaxAnswer();
|
|
void displayAnimFrame(int frameNum, int animId);
|
|
|
|
void copcha();
|
|
void adzon();
|
|
void premtet();
|
|
void ajchai();
|
|
void ecr2(Common::String text);
|
|
void tlu(int af, int ob);
|
|
void mennor();
|
|
void tsuiv();
|
|
void treg(int objId);
|
|
int rechai();
|
|
|
|
public:
|
|
Common::Point _prevPos;
|
|
int _currMenu;
|
|
int _currAction;
|
|
int _drawingSizeArr[108];
|
|
int _charAnswerCount[9];
|
|
int _charAnswerMax[9];
|
|
byte _tabdon[4001];
|
|
bool _soundOff;
|
|
bool _blo;
|
|
bool _destinationOk;
|
|
bool _largestClearScreen;
|
|
int _currGraphicalDevice;
|
|
int _newGraphicalDevice;
|
|
float _addFix;
|
|
int _savedBitIndex;
|
|
int _numpal;
|
|
int _key;
|
|
SaveStruct _coreVar, _saveStruct;
|
|
|
|
int _maff;
|
|
int _caff;
|
|
int _crep;
|
|
|
|
int _resolutionScaler;
|
|
byte _destinationArray[7][25];
|
|
|
|
// TODO: Replace the following with proper implementations, or refactor out the code using them
|
|
byte _mem[65536 * 16];
|
|
byte *_curPict;
|
|
byte *_curAnim;
|
|
byte *_rightFramePict;
|
|
byte *_compMusicBuf1;
|
|
byte *_compMusicBuf2;
|
|
|
|
Debugger _debugger;
|
|
ScreenSurface _screenSurface;
|
|
PaletteManager _paletteManager;
|
|
GfxSurface _backgroundSurface;
|
|
Common::RandomSource _randomSource;
|
|
SoundManager _soundManager;
|
|
SavegameManager _savegameManager;
|
|
SpeechManager _speechManager;
|
|
Menu _menu;
|
|
MouseHandler _mouse;
|
|
TextHandler _text;
|
|
DialogManager _dialogManager;
|
|
|
|
MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc);
|
|
~MortevielleEngine();
|
|
virtual bool hasFeature(EngineFeature f) const;
|
|
virtual bool canLoadGameStateCurrently();
|
|
virtual bool canSaveGameStateCurrently();
|
|
virtual Common::Error loadGameState(int slot);
|
|
virtual Common::Error saveGameState(int slot, const Common::String &desc);
|
|
virtual Common::Error run();
|
|
uint32 getGameFlags() const;
|
|
Common::Language getLanguage() const;
|
|
static Common::String generateSaveFilename(const Common::String &target, int slot);
|
|
Common::String generateSaveFilename(int slot) { return generateSaveFilename(_targetName, slot); }
|
|
|
|
int getChar();
|
|
bool keyPressed();
|
|
Common::Point getMousePos() const { return _mousePos; }
|
|
void setMousePos(const Common::Point &pt);
|
|
bool getMouseClick() const { return _mouseClick; }
|
|
void setMouseClick(bool v) { _mouseClick = v; }
|
|
Common::String getEngineString(int idx) const { return _engineStrings[idx]; }
|
|
Common::String getGameString(int idx) const { return _gameStrings[idx]; }
|
|
|
|
void delay(int amount);
|
|
void gameLoaded();
|
|
void initGame();
|
|
void displayAloneText();
|
|
void draw(int x, int y);
|
|
void charToHour();
|
|
void hourToChar();
|
|
Common::String getString(int num);
|
|
void setPal(int n);
|
|
Common::String copy(const Common::String &s, int idx, size_t size);
|
|
void testKeyboard();
|
|
int getPresence(int roomId);
|
|
void displayEmptyHand();
|
|
void displayPicture(const byte *pic, int x, int y);
|
|
|
|
int gettKeyPressed();
|
|
void handleDescriptionText(int f, int mesgId);
|
|
int getAnimOffset(int frameNum, int animNum);
|
|
|
|
void hirs();
|
|
};
|
|
|
|
extern MortevielleEngine *g_vm;
|
|
|
|
} // End of namespace Mortevielle
|
|
|
|
#endif
|