aboutsummaryrefslogtreecommitdiff
path: root/engines/adl/adl.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/adl/adl.h')
-rw-r--r--engines/adl/adl.h393
1 files changed, 393 insertions, 0 deletions
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
new file mode 100644
index 0000000000..c9d77fcc62
--- /dev/null
+++ b/engines/adl/adl.h
@@ -0,0 +1,393 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_ADL_H
+#define ADL_ADL_H
+
+#include "common/debug-channels.h"
+#include "common/array.h"
+#include "common/rect.h"
+#include "common/str.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/func.h"
+#include "common/scummsys.h"
+
+#include "engines/engine.h"
+
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
+#include "adl/console.h"
+#include "adl/disk.h"
+
+namespace Common {
+class ReadStream;
+class SeekableReadStream;
+class File;
+struct Event;
+}
+
+namespace Adl {
+
+class Console;
+class Display;
+class GraphicsMan;
+class Speaker;
+struct AdlGameDescription;
+class ScriptEnv;
+
+enum kDebugChannels {
+ kDebugChannelScript = 1 << 0
+};
+
+// Save and restore opcodes
+#define IDO_ACT_SAVE 0x0f
+#define IDO_ACT_LOAD 0x10
+
+#define IDI_CUR_ROOM 0xfc
+#define IDI_VOID_ROOM 0xfd
+#define IDI_ANY 0xfe
+
+#define IDI_WORD_SIZE 8
+
+enum Direction {
+ IDI_DIR_NORTH,
+ IDI_DIR_SOUTH,
+ IDI_DIR_EAST,
+ IDI_DIR_WEST,
+ IDI_DIR_UP,
+ IDI_DIR_DOWN,
+ IDI_DIR_TOTAL
+};
+
+struct Room {
+ Room() :
+ description(0),
+ picture(0),
+ curPicture(0) {
+ memset(connections, 0, sizeof(connections));
+ }
+
+ byte description;
+ byte connections[IDI_DIR_TOTAL];
+ DataBlockPtr data;
+ byte picture;
+ byte curPicture;
+ bool isFirstTime;
+};
+
+typedef Common::HashMap<byte, DataBlockPtr> PictureMap;
+
+typedef Common::Array<byte> Script;
+
+struct Command {
+ byte room;
+ byte verb, noun;
+ byte numCond, numAct;
+ Script script;
+};
+
+class ScriptEnv {
+public:
+ ScriptEnv(const Command &cmd, byte room, byte verb, byte noun) :
+ _cmd(cmd), _room(room), _verb(verb), _noun(noun), _ip(0) { }
+
+ byte op() const { return _cmd.script[_ip]; }
+ // We keep this 1-based for easier comparison with the original engine
+ byte arg(uint i) const { return _cmd.script[_ip + i]; }
+ void skip(uint i) { _ip += i; }
+
+ bool isMatch() const {
+ return (_cmd.room == IDI_ANY || _cmd.room == _room) &&
+ (_cmd.verb == IDI_ANY || _cmd.verb == _verb) &&
+ (_cmd.noun == IDI_ANY || _cmd.noun == _noun);
+ }
+
+ byte getCondCount() const { return _cmd.numCond; }
+ byte getActCount() const { return _cmd.numAct; }
+ byte getNoun() const { return _noun; }
+ const Command &getCommand() const { return _cmd; }
+
+private:
+ const Command &_cmd;
+ const byte _room, _verb, _noun;
+ byte _ip;
+};
+
+enum {
+ IDI_ITEM_NOT_MOVED,
+ IDI_ITEM_DROPPED,
+ IDI_ITEM_DOESNT_MOVE
+};
+
+struct Item {
+ byte id;
+ byte noun;
+ byte room;
+ byte picture;
+ bool isLineArt;
+ Common::Point position;
+ int state;
+ byte description;
+ Common::Array<byte> roomPictures;
+ bool isOnScreen;
+};
+
+struct Time {
+ byte hours, minutes;
+
+ Time() : hours(12), minutes(0) { }
+};
+
+struct State {
+ Common::Array<Room> rooms;
+ Common::List<Item> items;
+ Common::Array<byte> vars;
+
+ byte room;
+ uint16 moves;
+ bool isDark;
+ Time time;
+
+ State() : room(1), moves(1), isDark(false) { }
+};
+
+typedef Common::List<Command> Commands;
+typedef Common::HashMap<Common::String, uint> WordMap;
+
+struct RoomData {
+ Common::String description;
+ PictureMap pictures;
+ Commands commands;
+};
+
+// Opcode debugging macros
+#define OP_DEBUG_0(F) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
+ return 0; \
+} while (0)
+
+#define OP_DEBUG_1(F, P1) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
+ return 1; \
+} while (0)
+
+#define OP_DEBUG_2(F, P1, P2) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
+ return 2; \
+} while (0)
+
+#define OP_DEBUG_3(F, P1, P2, P3) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
+ return 3; \
+} while (0)
+
+#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
+ return 4; \
+} while (0)
+
+class AdlEngine : public Engine {
+friend class Console;
+public:
+ virtual ~AdlEngine();
+
+ bool pollEvent(Common::Event &event) const;
+
+protected:
+ AdlEngine(OSystem *syst, const AdlGameDescription *gd);
+
+ // Engine
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const Common::String &desc);
+
+ Common::String readString(Common::ReadStream &stream, byte until = 0) const;
+ Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
+ void openFile(Common::File &file, const Common::String &name) const;
+
+ virtual void printString(const Common::String &str) = 0;
+ virtual Common::String loadMessage(uint idx) const = 0;
+ virtual void printMessage(uint idx);
+ virtual Common::String getItemDescription(const Item &item) const;
+ void delay(uint32 ms) const;
+
+ Common::String inputString(byte prompt = 0) const;
+ byte inputKey(bool showCursor = true) const;
+
+ virtual Common::String formatVerbError(const Common::String &verb) const;
+ virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
+ void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
+ void readCommands(Common::ReadStream &stream, Commands &commands);
+ void checkInput(byte verb, byte noun);
+ virtual bool isInputValid(byte verb, byte noun, bool &is_any);
+ virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
+
+ virtual void setupOpcodeTables();
+ virtual void initState();
+ virtual byte roomArg(byte room) const;
+ virtual void advanceClock() { }
+
+ // Opcodes
+ int o1_isItemInRoom(ScriptEnv &e);
+ int o1_isMovesGT(ScriptEnv &e);
+ int o1_isVarEQ(ScriptEnv &e);
+ int o1_isCurPicEQ(ScriptEnv &e);
+ int o1_isItemPicEQ(ScriptEnv &e);
+
+ int o1_varAdd(ScriptEnv &e);
+ int o1_varSub(ScriptEnv &e);
+ int o1_varSet(ScriptEnv &e);
+ int o1_listInv(ScriptEnv &e);
+ int o1_moveItem(ScriptEnv &e);
+ int o1_setRoom(ScriptEnv &e);
+ int o1_setCurPic(ScriptEnv &e);
+ int o1_setPic(ScriptEnv &e);
+ int o1_printMsg(ScriptEnv &e);
+ int o1_setLight(ScriptEnv &e);
+ int o1_setDark(ScriptEnv &e);
+ int o1_save(ScriptEnv &e);
+ int o1_restore(ScriptEnv &e);
+ int o1_restart(ScriptEnv &e);
+ int o1_quit(ScriptEnv &e);
+ int o1_placeItem(ScriptEnv &e);
+ int o1_setItemPic(ScriptEnv &e);
+ int o1_resetPic(ScriptEnv &e);
+ template <Direction D>
+ int o1_goDirection(ScriptEnv &e);
+ int o1_takeItem(ScriptEnv &e);
+ int o1_dropItem(ScriptEnv &e);
+ int o1_setRoomPic(ScriptEnv &e);
+
+ // Graphics
+ void clearScreen() const;
+ void drawPic(byte pic, Common::Point pos = Common::Point()) const;
+
+ // Sound
+ void bell(uint count = 1) const;
+
+ // Game state functions
+ const Room &getRoom(uint i) const;
+ Room &getRoom(uint i);
+ const Room &getCurRoom() const;
+ Room &getCurRoom();
+ const Item &getItem(uint i) const;
+ Item &getItem(uint i);
+ byte getVar(uint i) const;
+ void setVar(uint i, byte value);
+ virtual void takeItem(byte noun);
+ void dropItem(byte noun);
+ bool matchCommand(ScriptEnv &env) const;
+ void doActions(ScriptEnv &env);
+ bool doOneCommand(const Commands &commands, byte verb, byte noun);
+ void doAllCommands(const Commands &commands, byte verb, byte noun);
+
+ // Debug functions
+ static Common::String toAscii(const Common::String &str);
+ Common::String itemStr(uint i) const;
+ Common::String roomStr(uint i) const;
+ Common::String itemRoomStr(uint i) const;
+ Common::String verbStr(uint i) const;
+ Common::String nounStr(uint i) const;
+ Common::String msgStr(uint i) const;
+ Common::String dirStr(Direction dir) const;
+ bool op_debug(const char *fmt, ...) const;
+ Common::DumpFile *_dumpFile;
+
+ Display *_display;
+ GraphicsMan *_graphics;
+ Speaker *_speaker;
+
+ // Opcodes
+ typedef Common::Functor1<ScriptEnv &, int> Opcode;
+ Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
+ // Message strings in data file
+ Common::Array<DataBlockPtr> _messages;
+ // Picture data
+ PictureMap _pictures;
+ // Dropped item screen offsets
+ Common::Array<Common::Point> _itemOffsets;
+ // <room, verb, noun, script> lists
+ Commands _roomCommands;
+ Commands _globalCommands;
+ // Data related to the current room
+ RoomData _roomData;
+
+ WordMap _verbs;
+ WordMap _nouns;
+ Common::StringArray _priVerbs;
+ Common::StringArray _priNouns;
+
+ struct {
+ Common::String enterCommand;
+ Common::String verbError;
+ Common::String nounError;
+ Common::String playAgain;
+ Common::String pressReturn;
+ Common::String lineFeeds;
+ } _strings;
+
+ struct {
+ uint cantGoThere;
+ uint dontUnderstand;
+ uint itemDoesntMove;
+ uint itemNotHere;
+ uint thanksForPlaying;
+ } _messageIds;
+
+ // Game state
+ State _state;
+
+ bool _isRestarting, _isRestoring;
+ bool _skipOneCommand;
+
+private:
+ virtual void runIntro() const { }
+ virtual void init() = 0;
+ virtual void initGameState() = 0;
+ virtual void drawItems() = 0;
+ virtual void drawItem(Item &item, const Common::Point &pos) = 0;
+ virtual void loadRoom(byte roomNr) = 0;
+ virtual void showRoom() = 0;
+
+ // Engine
+ Common::Error run();
+ bool hasFeature(EngineFeature f) const;
+ bool canLoadGameStateCurrently();
+ bool canSaveGameStateCurrently();
+
+ // Text input
+ byte convertKey(uint16 ascii) const;
+ Common::String getLine() const;
+ Common::String getWord(const Common::String &line, uint &index) const;
+ void getInput(uint &verb, uint &noun);
+
+ Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
+ const AdlGameDescription *_gameDescription;
+ byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
+ bool _canSaveNow, _canRestoreNow;
+};
+
+} // End of namespace Adl
+
+#endif