diff options
Diffstat (limited to 'engines/m4/converse.h')
-rw-r--r-- | engines/m4/converse.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/engines/m4/converse.h b/engines/m4/converse.h new file mode 100644 index 0000000000..bea90d9ddf --- /dev/null +++ b/engines/m4/converse.h @@ -0,0 +1,200 @@ +/* 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_CONVERSE_H +#define M4_CONVERSE_H + +#include "common/array.h" +#include "common/hashmap.h" + +#include "m4/globals.h" +#include "m4/m4.h" +#include "m4/viewmgr.h" + +namespace M4 { + +enum ConversationState { + kConversationOptionsShown = 0, + kEntryIsActive = 1, + kReplyIsActive = 2, + kNoConversation = 3 +}; + +enum EntryType { + kVariable = 0, + kNode = 1, + kLinearNode = 2, + kEntry = 3, + kReply = 4, + kWeightedReply = 5 +}; + +// Flags are: +// bit 0: if it's 1, the entry is "initial", i.e. not hidden when the dialog starts +// bit 1: if it's 1, the entry persists if selected +enum EntryFlags { + kEntryInitial = 1, // byte 0 + kEntryPersists = 2 // byte 1 +}; + +enum EntryActionType { + kUnknownAction = 0, + kGotoEntry = 1, + kHideEntry = 2, + kUnhideEntry = 3, + kDestroyEntry = 4, + kAssignValue = 5, + kExitConv = 6 +}; + +enum LogicOp { + kOpPercent = 405, + kOpGreaterOrEqual = 421, + kOpLessOrEqual = 420, + kOpGreaterThan = 413, + kOpLessThan = 412, + kOpNotEqual = 422, + kOpCondNotEqual = 448, + kOpAssign = 407, + kOpAnd = 444, + kOpOr = 445 +}; + +struct Condition { + int32 offset; + int32 op; + int32 val; +}; + +struct EntryAction { + int32 targetOffset; // absolute offset (inside the *.chk file) of the action's target + int32 value; // the value set by assignment chunks + EntryActionType actionType; + EntryType targetType; + int32 nodeId; + int32 entryId; + bool isConditional; + Condition condition; +}; + +struct ConvEntry { + EntryType entryType; + int32 id; + int32 offset; // absolute offset inside the *.chk file, referenced by other chunks + int32 size; // entry action data size (for MADS games) + int32 flags; + int32 fallthroughMinEntries; + int32 fallthroughOffset; + int32 weight; // weight for weighted replies + int32 totalWeight; + uint16 entryCount; // entries inside this node (for MADS games) + char voiceFile[10]; + char text[512]; + bool autoSelect; + bool visible; + bool isConditional; + Condition condition; + Common::Array<EntryAction*>actions; + Common::Array<ConvEntry*>entries; +}; + +struct EntryInfo { + EntryType targetType; + int32 nodeIndex; + int32 entryIndex; +}; + +struct MessageEntry { + Common::Array<char*>messageStrings; +}; + +enum ConverseStyle {CONVSTYLE_EARTH, CONVSTYLE_SPACE}; + +typedef Common::HashMap<Common::String,EntryInfo,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> OffsetHashMap; +typedef Common::HashMap<Common::String,int32,Common::IgnoreCase_Hash,Common::IgnoreCase_EqualTo> ConvVarHashMap; + +class ConversationView: public View { +public: + ConversationView(M4Engine *vm); + ~ConversationView(); + void setNode(int32 nodeIndex); + + void onRefresh(RectList *rects, M4Surface *destSurface); + bool onEvent(M4EventType eventType, int param, int x, int y, bool &captureEvents); + int32 getCurrentNodeIndex() { return _currentNodeIndex; } + void selectEntry(int entryIndex); + +private: + void updateState(); + void playNextReply(); + + int32 _currentNodeIndex; + Common::Array<ConvEntry *> _activeItems; + int _highlightedIndex; + int _xEnd; + bool _entriesShown; + ConversationState _conversationState; + SndHandle *_currentHandle; +}; + +class Converse { + +public: + Converse(M4Engine *vm) : _vm(vm) {} + ~Converse() {} + + void startConversation(const char *convName, bool showConversebox = true, ConverseStyle style = CONVSTYLE_EARTH ); + void endConversation(); + const EntryInfo* getEntryInfo(int32 offset); + ConvEntry *getNode(int32 index) { return _convNodes[index]; } + + void setValue(int32 offset, int32 value); + const int32 getValue(int32 offset); + bool evaluateCondition(int32 leftVal, int32 op, int32 rightVal); + bool performAction(EntryAction *action); + /* + void resume() { play(); } + void play(); + */ +private: + M4Engine *_vm; + Common::Array<ConvEntry*>_convNodes; + Common::Array<MessageEntry*>_madsMessageList; + Common::Array<char *>_convStrings; + bool _playerCommandsAllowed; + bool _interfaceWasVisible; + ConverseStyle _style; + OffsetHashMap _offsetMap; + ConvVarHashMap _variables; + + void loadConversation(const char *convName); + void loadConversationMads(const char *convName); + void readConvEntryActions(Common::SubReadStream *convS, ConvEntry *curEntry); + void setEntryInfo(int32 offset, EntryType type, int32 nodeIndex, int32 entryIndex); +}; + +} // End of namespace M4 + +#endif |