/* 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::Arrayactions; Common::Arrayentries; }; struct EntryInfo { EntryType targetType; int32 nodeIndex; int32 entryIndex; }; struct MessageEntry { Common::ArraymessageStrings; }; enum ConverseStyle {CONVSTYLE_EARTH, CONVSTYLE_SPACE}; typedef Common::HashMap OffsetHashMap; typedef Common::HashMap 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 _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); 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_convNodes; Common::Array_madsMessageList; Common::Array_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