2008-04-20 14:47:37 +00:00
|
|
|
/* 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/viewmgr.h"
|
2010-03-07 05:06:58 +00:00
|
|
|
#include "m4/sound.h"
|
2008-04-20 14:47:37 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2010-01-31 00:47:29 +00:00
|
|
|
class ConversationView : public View {
|
2008-04-20 14:47:37 +00:00
|
|
|
public:
|
2010-01-30 09:21:07 +00:00
|
|
|
ConversationView(MadsM4Engine *vm);
|
2008-04-20 14:47:37 +00:00
|
|
|
~ConversationView();
|
|
|
|
void setNode(int32 nodeIndex);
|
|
|
|
|
|
|
|
void onRefresh(RectList *rects, M4Surface *destSurface);
|
2009-12-20 07:09:40 +00:00
|
|
|
bool onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents);
|
2008-04-20 14:47:37 +00:00
|
|
|
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:
|
2010-01-30 09:21:07 +00:00
|
|
|
Converse(MadsM4Engine *vm) : _vm(vm) {}
|
2008-04-20 14:47:37 +00:00
|
|
|
~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);
|
2008-06-09 17:50:52 +00:00
|
|
|
int32 getValue(int32 offset);
|
2008-04-20 14:47:37 +00:00
|
|
|
bool evaluateCondition(int32 leftVal, int32 op, int32 rightVal);
|
|
|
|
bool performAction(EntryAction *action);
|
|
|
|
/*
|
|
|
|
void resume() { play(); }
|
|
|
|
void play();
|
|
|
|
*/
|
|
|
|
private:
|
2010-01-30 09:21:07 +00:00
|
|
|
MadsM4Engine *_vm;
|
2008-04-20 14:47:37 +00:00
|
|
|
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);
|
|
|
|
};
|
|
|
|
|
2010-03-07 05:06:58 +00:00
|
|
|
|
|
|
|
struct MadsTalkEntry {
|
|
|
|
uint16 id;
|
|
|
|
const char *desc;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MADS_TALK_SIZE 5
|
|
|
|
|
|
|
|
class MadsConversation {
|
|
|
|
private:
|
|
|
|
MadsTalkEntry _talkList[MADS_TALK_SIZE];
|
|
|
|
public:
|
|
|
|
MadsConversation();
|
|
|
|
|
|
|
|
MadsTalkEntry &operator[](int index) { return _talkList[index]; }
|
|
|
|
};
|
|
|
|
|
2008-04-20 14:47:37 +00:00
|
|
|
} // End of namespace M4
|
|
|
|
|
|
|
|
#endif
|