/* 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 PARALLACTION_ZONE_H #define PARALLACTION_ZONE_H #include "common/list.h" #include "common/ptr.h" #include "parallaction/graphics.h" namespace Parallaction { struct Zone; struct Animation; struct Command; struct Question; struct Answer; struct Instruction; struct Program; typedef Common::SharedPtr<Zone> ZonePtr; typedef Common::List<ZonePtr> ZoneList; typedef Common::SharedPtr<Animation> AnimationPtr; typedef Common::List<AnimationPtr> AnimationList; typedef Common::SharedPtr<Instruction> InstructionPtr; typedef Common::Array<InstructionPtr> InstructionList; typedef Common::List<Common::Point> PointList; enum ZoneTypes { kZoneExamine = 1, // zone displays comment if activated kZoneDoor = 2, // zone activated on click (after some walk if needed) kZoneGet = 3, // for pickable items kZoneMerge = 4, // tags items which can be merged in inventory kZoneTaste = 5, // NEVER USED kZoneHear = 6, // NEVER USED: they ran out of time before integrating sfx kZoneFeel = 7, // NEVER USED kZoneSpeak = 8, // tags NPCs the character can talk with kZoneNone = 9, // used to prevent parsing on peculiar Animations kZoneTrap = 10, // zone activated when character enters kZoneYou = 11, // marks the character kZoneCommand = 12, // BRA specific kZonePath = 13, // defines nodes for assisting walk calculation routines kZoneBox = 14 }; enum ZoneFlags { kFlagsClosed = 1, // Zone: door is closed / switch is off kFlagsActive = 2, // Zone/Animation: object is visible kFlagsRemove = 4, // Zone/Animation: object is soon to be removed kFlagsActing = 8, // Animation: script execution is active kFlagsLocked = 0x10, // Zone: door or switch cannot be toggled kFlagsFixed = 0x20, // Zone: Zone item cannot be picked up kFlagsNoName = 0x40, // Zone with no name (used to prevent some kEvEnterZone events) kFlagsNoMasked = 0x80, // Animation is to be drawn ignoring z buffer kFlagsLooping = 0x100, // Animation: script is to be executed repeatedly kFlagsAdded = 0x200, // NEVER USED in Nippon Safes kFlagsCharacter = 0x400, // kFlagsNoWalk = 0x800, // Zone: character doesn't need to walk towards object to interact // BRA specific kFlagsYourself = 0x1000, // BRA: marks zones used by the character on him/herself kFlagsScaled = 0x2000, kFlagsSelfuse = 0x4000, // BRA: marks zones to be preserved across location changes (see Parallaction::freeZones) kFlagsIsAnimation = 0x1000000, // BRA: used in walk code (trap check), to tell is a Zone is an Animation kFlagsAnimLinked = 0x2000000 }; enum CommandFlags { kFlagsAll = 0xFFFFFFFFU, kFlagsVisited = 1, kFlagsExit = 0x10000000, kFlagsEnter = 0x20000000, kFlagsGlobal = 0x40000000, // BRA specific kFlagsTestTrue = 2 }; struct Command { uint16 _id; uint32 _flagsOn; uint32 _flagsOff; bool _valid; Command(); ~Command(); // Common fields uint32 _flags; ZonePtr _zone; Common::String _zoneName; char* _string; uint16 _callable; uint16 _object; Common::Point _move; // BRA specific Common::Point _startPos; Common::Point _startPos2; Common::String _counterName; int _counterValue; int _zeta0; int _zeta1; int _zeta2; int _characterId; char* _string2; int _musicCommand; int _musicParm; }; typedef Common::SharedPtr<Command> CommandPtr; typedef Common::List<CommandPtr> CommandList; #define NUM_QUESTIONS 40 #define NUM_ANSWERS 20 struct Answer { Common::String _text; uint16 _mood; Common::String _followingName; CommandList _commands; uint32 _noFlags; uint32 _yesFlags; // BRA specific bool _hasCounterCondition; Common::String _counterName; int _counterValue; int _counterOp; Answer(); bool textIsNull(); int speakerMood(); }; struct Question { Common::String _name; Common::String _text; uint16 _mood; Answer* _answers[NUM_ANSWERS]; Question(const Common::String &name); ~Question(); bool textIsNull(); int speakerMood(); int balloonWinding(); }; struct Dialogue { Question *_questions[NUM_QUESTIONS]; uint _numQuestions; Question *findQuestion(const Common::String &name) const; void addQuestion(Question *q); Dialogue(); ~Dialogue(); }; #define MAX_WALKPOINT_LISTS 20 #define FREE_HEAR_CHANNEL -1 #define MUSIC_HEAR_CHANNEL -2 struct TypeData { // common GfxObj *_gfxobj; // get, examine, door Common::String _filename; // speak, examine, hear // get uint32 _getIcon; // speak Dialogue *_speakDialogue; // examine Common::String _examineText; // door Common::String _doorLocation; Common::Point _doorStartPos; uint16 _doorStartFrame; Common::Point _doorStartPos2_br; uint16 _doorStartFrame2_br; // hear int _hearChannel; int _hearFreq; // merge uint32 _mergeObj1; uint32 _mergeObj2; uint32 _mergeObj3; // path int _pathNumLists; PointList _pathLists[MAX_WALKPOINT_LISTS]; TypeData() { _gfxobj = 0; _getIcon = 0; _speakDialogue = 0; _doorStartFrame = 0; _doorStartPos.x = -1000; _doorStartPos.y = -1000; _doorStartFrame2_br = 0; _doorStartPos2_br.x = -1000; _doorStartPos2_br.y = -1000; _hearChannel = FREE_HEAR_CHANNEL; _hearFreq = -1; _mergeObj1 = 0; _mergeObj2 = 0; _mergeObj3 = 0; _pathNumLists = 0; } ~TypeData() { if (_gfxobj) { _gfxobj->release(); } delete _speakDialogue; } }; #define ACTIONTYPE(z) ((z)->_type & 0xFFFF) #define ITEMTYPE(z) ((z)->_type & 0xFFFF0000) #define PACK_ZONETYPE(zt,it) (((zt) & 0xFFFF) | (((it) & 0xFFFF) << 16)) #define ZONENAME_LENGTH 32 #define INVALID_LOCATION_INDEX ((uint32)-1) #define INVALID_ZONE_INDEX ((uint32)-1) struct Zone { private: int16 _right; int16 _bottom; protected: int16 _left; int16 _top; public: char _name[ZONENAME_LENGTH]; uint32 _type; uint32 _flags; GfxObj *_label; TypeData u; CommandList _commands; Common::Point _moveTo; // BRA specific uint _index; uint _locationIndex; Common::String _linkedName; AnimationPtr _linkedAnim; Zone(); virtual ~Zone(); void translate(int16 x, int16 y); bool hitRect(int x, int y) const; void setRect(int16 left, int16 top, int16 right, int16 bottom) { setX(left); setY(top); _right = right; _bottom = bottom; } void getRect(Common::Rect& r) { r.left = _left; r.right = _right; r.top = _top; r.bottom = _bottom; } // getters/setters virtual int16 getX() { return _left; } virtual void setX(int16 value) { _left = value; } virtual int16 getY() { return _top; } virtual void setY(int16 value) { _top = value; } }; struct LocalVariable { protected: int16 _value; int16 _min; int16 _max; public: LocalVariable() { _value = 0; _min = -10000; _max = 10000; } void setRange(int16 min, int16 max); int16 getValue() const; void setValue(int16 value); }; enum ParaFlags { kParaImmediate = 1, // instruction is using an immediate parameter kParaLocal = 2, // instruction is using a local variable kParaField = 0x10, // instruction is using an animation's field kParaRandom = 0x100, kParaLValue = 0x20 }; struct AnimationField { typedef Common::Functor0Mem<int16, Animation> Accessor; typedef Common::Functor1Mem<int16, void, Animation> Mutator; typedef Accessor::FuncType AccessorFunc; typedef Mutator::FuncType MutatorFunc; protected: Accessor *_accessor; Mutator *_mutator; public: AnimationField(Animation* instance, AccessorFunc accessor, MutatorFunc mutator) { _accessor = new Accessor(instance, accessor); _mutator = new Mutator(instance, mutator); } AnimationField(Animation* instance, AccessorFunc accessor) { _accessor = new Accessor(instance, accessor); _mutator = 0; } ~AnimationField() { delete _accessor; delete _mutator; } int16 getValue() const { assert(_accessor); return (*_accessor)(); } void setValue(int16 value) { assert(_mutator); (*_mutator)(value); } }; struct ScriptVar { uint32 _flags; int16 _value; LocalVariable* _local; AnimationField* _field; ScriptVar(); ~ScriptVar(); int16 getValue(); void setValue(int16 value); void setLocal(LocalVariable *local); void setField(Animation *anim, AnimationField::AccessorFunc accessor, AnimationField::MutatorFunc mutator); void setField(Animation *anim, AnimationField::AccessorFunc accessor); void setImmediate(int16 value); void setRandom(int16 seed); }; enum InstructionFlags { kInstMod = 4, kInstMaskedPut = 8, kInstUnk20 = 0x20 }; struct Instruction { uint32 _index; uint32 _flags; // common AnimationPtr _a; ZonePtr _z; int16 _immediate; ScriptVar _opA; ScriptVar _opB; // BRA specific byte _colors[3]; ScriptVar _opC; char *_text; char *_text2; int _y; uint32 _endif; Instruction(); ~Instruction(); }; enum { kProgramIdle, // awaiting execution kProgramRunning, // running kProgramDone // execution completed }; struct Program { AnimationPtr _anim; LocalVariable *_locals; uint16 _loopCounter; uint16 _numLocals; uint32 _ip; uint32 _loopStart; InstructionList _instructions; uint32 _status; Program(); ~Program(); int16 findLocal(const char* name); int16 addLocal(const char *name, int16 value = 0, int16 min = -10000, int16 max = 10000); }; typedef Common::SharedPtr<Program> ProgramPtr; typedef Common::List<ProgramPtr> ProgramList; struct Animation : public Zone { protected: int16 _frame; int16 _z; public: GfxObj *gfxobj; char *_scriptName; Animation(); virtual ~Animation(); uint16 getFrameNum() const; byte* getFrameData() const; void resetZ(); bool hitFrameRect(int x, int y) const; void getFrameRect(Common::Rect &r) const; int16 getBottom() const; // HACK: this routine is only used to download initialisation // parameter to a script used when moving sarcophagi around in // the museum. It bypasses all the consistency checks that // can be performed by the individual setters. See the comment // in startMovingSarcophagus() in callables_ns.cpp void forceXYZF(int16 x, int16 y, int16 z, int16 f); // getters/setters used by scripts int16 getX() { return _left; } void setX(int16 value) { _left = value; } int16 getY() { return _top; } void setY(int16 value) { _top = value; } int16 getZ() { return _z; } void setZ(int16 value) { _z = value; } int16 getF() { return _frame; } void setF(int16 value); void getFoot(Common::Point &foot); void setFoot(const Common::Point &foot); }; class Table { protected: char **_data; uint16 _size; uint16 _used; bool _disposeMemory; public: Table(uint32 size); Table(uint32 size, const char** data); virtual ~Table(); enum { notFound = 0 }; uint count() const { return _used; } const char *item(uint index) const; virtual void addData(const char* s); virtual void clear(); virtual uint16 lookup(const char* s); }; class FixedTable : public Table { uint16 _numFixed; public: FixedTable(uint32 size, uint32 fixed); void clear(); }; Table* createTableFromStream(uint32 size, Common::SeekableReadStream *stream); } // namespace Parallaction #endif