mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-23 18:24:59 +00:00
2cae2fc4d0
svn-id: r54563
404 lines
9.8 KiB
C++
404 lines
9.8 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.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#ifndef M4_GLOBALS_H
|
|
#define M4_GLOBALS_H
|
|
|
|
#include "common/scummsys.h"
|
|
#include "common/array.h"
|
|
#include "common/hashmap.h"
|
|
#include "common/rect.h"
|
|
#include "common/list.h"
|
|
#include "common/ptr.h"
|
|
|
|
namespace Common {
|
|
class SeekableReadStream;
|
|
}
|
|
|
|
namespace M4 {
|
|
|
|
class MadsM4Engine;
|
|
class M4Engine;
|
|
class MadsEngine;
|
|
class ScriptInterpreter;
|
|
class ScriptFunction;
|
|
|
|
// Globals
|
|
enum WoodScriptGlobals {
|
|
kGlobTime = 0,
|
|
kGlobTimeDelta = 1,
|
|
kGlobMinY = 2,
|
|
kGlobMaxY = 3,
|
|
kGlobMinScale = 4,
|
|
kGlobMaxScale = 5,
|
|
kGlobScaler = 6,
|
|
kGlobTemp1 = 7,
|
|
kGlobTemp2 = 8,
|
|
kGlobTemp3 = 9,
|
|
kGlobTemp4 = 10,
|
|
kGlobTemp5 = 11,
|
|
kGlobTemp6 = 12,
|
|
kGlobTemp7 = 13,
|
|
kGlobTemp8 = 14,
|
|
kGlobTemp9 = 15,
|
|
kGlobTemp10 = 16,
|
|
kGlobTemp11 = 17,
|
|
kGlobTemp12 = 18,
|
|
kGlobTemp13 = 19,
|
|
kGlobTemp14 = 20,
|
|
kGlobTemp15 = 21,
|
|
kGlobTemp16 = 22,
|
|
kGlobTemp17 = 23,
|
|
kGlobTemp18 = 24,
|
|
kGlobTemp19 = 25,
|
|
kGlobTemp20 = 26,
|
|
kGlobTemp21 = 27,
|
|
kGlobTemp22 = 28,
|
|
kGlobTemp23 = 29,
|
|
kGlobTemp24 = 30,
|
|
kGlobTemp25 = 31,
|
|
kGlobTemp26 = 32,
|
|
kGlobTemp27 = 33,
|
|
kGlobTemp28 = 34,
|
|
kGlobTemp29 = 35,
|
|
kGlobTemp30 = 36,
|
|
kGlobTemp31 = 37,
|
|
kGlobTemp32 = 38
|
|
};
|
|
|
|
const uint32 SERIES_FORWARD = 0;
|
|
const uint32 SERIES_PINGPONG = 1;
|
|
const uint32 SERIES_BACKWARD = 2;
|
|
const uint32 SERIES_RANDOM = 4;
|
|
const uint32 SERIES_NO_TOSS = 8;
|
|
const uint32 SERIES_STICK = 16;
|
|
const uint32 SERIES_LOOP_TRIGGER = 32;
|
|
const uint32 SERIES_LOAD_PALETTE = 64;
|
|
const uint32 SERIES_HORZ_FLIP =128;
|
|
|
|
enum KernelTriggerType {
|
|
KT_PARSE = 1,
|
|
KT_DAEMON,
|
|
KT_PREPARSE
|
|
};
|
|
|
|
class Kernel {
|
|
private:
|
|
MadsM4Engine *_vm;
|
|
ScriptFunction *_globalDaemonFn, *_globalParserFn;
|
|
ScriptFunction *_sectionInitFn, *_sectionDaemonFn, *_sectionParserFn;
|
|
ScriptFunction *_roomInitFn, *_roomDaemonFn, *_roomPreParserFn, *_roomParserFn;
|
|
void pauseEngines();
|
|
void unpauseEngines();
|
|
public:
|
|
Kernel(MadsM4Engine *vm);
|
|
|
|
// TODO: Move to some palette/fading class
|
|
int fadeUpDuration, firstFadeColorIndex;
|
|
int minPalEntry, maxPalEntry;
|
|
|
|
bool paused;
|
|
//machine* myWalker;
|
|
bool repeatedlyCallDeamon;
|
|
bool daemonTriggerAvailable;
|
|
bool betweenRooms;
|
|
int currentSection, newSection, previousSection;
|
|
int currentRoom, newRoom, previousRoom;
|
|
|
|
int32 trigger;
|
|
KernelTriggerType triggerMode;
|
|
|
|
int32 createTrigger(int32 triggerNum);
|
|
bool sendTrigger(int32 triggerNum);
|
|
bool handleTrigger(int32 triggerNum);
|
|
|
|
void loadGlobalScriptFunctions();
|
|
void loadSectionScriptFunctions();
|
|
void loadRoomScriptFunctions();
|
|
|
|
void globalDaemon();
|
|
void globalParser();
|
|
|
|
void sectionInit();
|
|
void sectionDaemon();
|
|
void sectionParser();
|
|
|
|
void roomInit();
|
|
void roomDaemon();
|
|
void roomPreParser();
|
|
void roomParser();
|
|
|
|
void pauseGame(bool value);
|
|
};
|
|
|
|
#define TOTAL_NUM_VARIABLES 210
|
|
|
|
#define PLAYER_INVENTORY 2
|
|
|
|
enum MADSArticles {
|
|
kArticleNone = 0,
|
|
kArticleWith = 1,
|
|
kArticleTo = 2,
|
|
kArticleAt = 3,
|
|
kArticleFrom = 4,
|
|
kArticleOn = 5,
|
|
kArticleIn = 6,
|
|
kArticleUnder = 7,
|
|
kArticleBehind = 8
|
|
};
|
|
|
|
struct VocabEntry {
|
|
uint8 flags1;
|
|
uint8 flags2;
|
|
uint16 vocabId;
|
|
};
|
|
|
|
class MadsObject {
|
|
public:
|
|
MadsObject() {}
|
|
MadsObject(Common::SeekableReadStream *stream);
|
|
void load(Common::SeekableReadStream *stream);
|
|
bool isInInventory() const { return roomNumber == PLAYER_INVENTORY; }
|
|
|
|
uint16 descId;
|
|
uint16 roomNumber;
|
|
MADSArticles article;
|
|
uint8 vocabCount;
|
|
VocabEntry vocabList[3];
|
|
};
|
|
|
|
typedef Common::Array<Common::SharedPtr<MadsObject> > MadsObjectArray;
|
|
|
|
class Globals {
|
|
private:
|
|
MadsM4Engine *_vm;
|
|
public:
|
|
Globals(MadsM4Engine *vm);
|
|
virtual ~Globals() {}
|
|
|
|
bool isInterfaceVisible();
|
|
|
|
};
|
|
|
|
class M4Globals : public Globals {
|
|
private:
|
|
M4Engine *_vm;
|
|
public:
|
|
M4Globals(M4Engine *vm);
|
|
virtual ~M4Globals() {}
|
|
|
|
bool invSuppressClickSound;
|
|
};
|
|
|
|
enum RexPlayerSex { SEX_MALE = 0, SEX_FEMALE = 2, SEX_UNKNOWN = 1};
|
|
|
|
enum MadsDialogType { DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3, DIALOG_OPTIONS = 4,
|
|
DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6};
|
|
|
|
struct MadsConfigData {
|
|
bool musicFlag;
|
|
bool soundFlag;
|
|
bool easyMouse;
|
|
bool invObjectsStill;
|
|
bool textWindowStill;
|
|
int storyMode;
|
|
int screenFades;
|
|
};
|
|
|
|
#define GET_GLOBAL(x) (_madsVm->globals()->_globals[x])
|
|
#define GET_GLOBAL32(x) (((uint32)_madsVm->globals()->_globals[x + 1] << 16) | _madsVm->globals()->_globals[x])
|
|
#define SET_GLOBAL(x,y) _madsVm->globals()->_globals[x] = y
|
|
#define SET_GLOBAL32(x,y) { _madsVm->globals()->_globals[x] = (y) & 0xffff; _madsVm->globals()->_globals[(x) + 1] = (y) >> 16; }
|
|
|
|
typedef int (*IntFunctionPtr)();
|
|
|
|
union DataMapEntry {
|
|
bool *boolValue;
|
|
uint16 *uint16Value;
|
|
int *intValue;
|
|
IntFunctionPtr fnPtr;
|
|
};
|
|
|
|
typedef Common::HashMap<uint16, uint16> DataMapHash;
|
|
|
|
enum DataMapType {BOOL, UINT16, INT, INT_FN};
|
|
|
|
class DataMapWrapper {
|
|
friend class DataMap;
|
|
private:
|
|
DataMapEntry _value;
|
|
DataMapType _type;
|
|
public:
|
|
DataMapWrapper(bool *v) { _value.boolValue = v; _type = BOOL; }
|
|
DataMapWrapper(uint16 *v) { _value.uint16Value = v; _type = UINT16; }
|
|
DataMapWrapper(int16 *v) { _value.uint16Value = (uint16 *)v; _type = UINT16; }
|
|
DataMapWrapper(int *v) { _value.intValue = v; _type = INT; }
|
|
DataMapWrapper(IntFunctionPtr v) { _value.fnPtr = v; _type = INT_FN; }
|
|
|
|
uint16 getIntValue() {
|
|
if (_type == BOOL) return *_value.boolValue ? 0xffff : 0;
|
|
else if (_type == UINT16) return *_value.uint16Value;
|
|
else if (_type == INT) return *_value.intValue;
|
|
else return _value.fnPtr();
|
|
}
|
|
void setIntValue(uint16 v) {
|
|
if (_type == BOOL) *_value.boolValue = v != 0;
|
|
else if (_type == UINT16) *_value.uint16Value = v;
|
|
else if (_type == INT) *_value.intValue = v;
|
|
}
|
|
};
|
|
|
|
#define MAP_DATA(V) _madsVm->globals()->_dataMap.addMapping(new DataMapWrapper(V))
|
|
|
|
class DataMap {
|
|
private:
|
|
DataMapHash _data;
|
|
Common::Array<DataMapWrapper *> _mapList;
|
|
public:
|
|
DataMap() {
|
|
_mapList.push_back(NULL);
|
|
}
|
|
~DataMap() {
|
|
for (uint i = 1; i < _mapList.size(); ++i)
|
|
delete _mapList[i];
|
|
}
|
|
|
|
void addMapping(DataMapWrapper *v) { _mapList.push_back(v); }
|
|
uint16 get(uint16 index) {
|
|
if (index < _mapList.size())
|
|
return _mapList[index]->getIntValue();
|
|
|
|
return _data[index];
|
|
}
|
|
void set(uint16 index, uint16 v) {
|
|
if (index < _mapList.size())
|
|
_mapList[index]->setIntValue(v);
|
|
else
|
|
_data[index] = v;
|
|
}
|
|
};
|
|
|
|
class MadsGlobals : public Globals {
|
|
private:
|
|
struct MessageItem {
|
|
uint32 id;
|
|
uint32 offset;
|
|
uint16 uncompSize;
|
|
uint16 compSize;
|
|
};
|
|
|
|
MadsEngine *_vm;
|
|
Common::Array<char* > _madsVocab;
|
|
Common::Array<char* > _madsQuotes;
|
|
Common::Array<MessageItem> _madsMessages;
|
|
MadsObjectArray _madsObjects;
|
|
Common::List<int> _visitedScenes;
|
|
public:
|
|
MadsGlobals(MadsEngine *vm);
|
|
~MadsGlobals();
|
|
|
|
// MADS variables
|
|
uint16 _globals[TOTAL_NUM_VARIABLES];
|
|
MadsConfigData _config;
|
|
bool playerSpriteChanged;
|
|
MadsDialogType dialogType;
|
|
int sceneNumber;
|
|
int previousScene;
|
|
int16 _nextSceneId;
|
|
uint16 actionNouns[3];
|
|
DataMap _dataMap;
|
|
int _difficultyLevel;
|
|
|
|
void loadMadsVocab();
|
|
uint32 getVocabSize() { return _madsVocab.size(); }
|
|
const char *getVocab(uint32 index) {
|
|
// Vocab list is 1-based, so always subtract one from index provided
|
|
assert((index > 0) && (index <= _madsVocab.size()));
|
|
return _madsVocab[index - 1];
|
|
}
|
|
|
|
void loadQuotes();
|
|
uint32 getQuotesSize() { return _madsQuotes.size(); }
|
|
const char *getQuote(uint32 index) { return _madsQuotes[index - 1]; }
|
|
// DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs
|
|
void clearQuotes() {}
|
|
void loadQuoteRange(int startNum, int endNum) {}
|
|
void loadQuoteSet(...) {}
|
|
void loadQuote(int quoteNum) {}
|
|
|
|
void loadMadsMessagesInfo();
|
|
uint32 getMessagesSize() { return _madsMessages.size(); }
|
|
int messageIndexOf(uint32 messageId);
|
|
const char *loadMessage(uint index);
|
|
|
|
void loadMadsObjects();
|
|
uint32 getObjectsSize() { return _madsObjects.size(); }
|
|
MadsObject *getObject(uint32 index) { return _madsObjects[index].get(); }
|
|
|
|
void addVisitedScene(int sceneNumber);
|
|
bool isSceneVisited(int sceneNumber);
|
|
void removeVisitedScene(int sceneNumber);
|
|
};
|
|
|
|
#define PLAYER_FIELD_LENGTH 40
|
|
|
|
class Player {
|
|
public:
|
|
Player(MadsM4Engine *vm);
|
|
void setCommandsAllowed(bool value);
|
|
|
|
// Variables
|
|
Common::Point position; // Player's current position
|
|
int facing; // Facing direction
|
|
|
|
char verb[PLAYER_FIELD_LENGTH]; // Action strings
|
|
char noun[PLAYER_FIELD_LENGTH];
|
|
char prep[PLAYER_FIELD_LENGTH];
|
|
char object[PLAYER_FIELD_LENGTH];
|
|
Common::String assetName, shadowName;
|
|
int walkerType, shadowType;
|
|
bool needToWalk, readyToWalk, waitingForWalk;
|
|
bool commandsAllowed;
|
|
bool commandReady;
|
|
bool visible;
|
|
bool beenInRoomBefore;
|
|
bool walkerInCurrentRoom;
|
|
int32 walkerTriggerNum;
|
|
int walkFacing;
|
|
bool setCommandsAllowedFlag;
|
|
|
|
bool said(const char *word1, const char *word2 = NULL, const char *word3 = NULL);
|
|
bool saidAny(const char *word1, const char *word2, const char *word3,
|
|
const char *word4, const char *word5, const char *word6, const char *word7,
|
|
const char *word8, const char *word9, const char *word10);
|
|
|
|
private:
|
|
MadsM4Engine *_vm;
|
|
};
|
|
|
|
} // End of namespace M4
|
|
|
|
#endif
|