Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

script.h

/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-0-0/engines/cine/script.h $
 * $Id: script.h 38287 2009-02-15 20:19:06Z lordhoto $
 *
 */

#ifndef CINE_SCRIPT_H
#define CINE_SCRIPT_H

#include "common/savefile.h"
#include "common/array.h"
#include "common/list.h"
#include "common/ptr.h"

namespace Cine {

#define SCRIPT_STACK_SIZE 50
#define LOCAL_VARS_SIZE 50

/*! \brief Fixed size array of script variables.
 *
 * Array size can be set in constructors, once the instance is created,
 * it cannot be changed directly.
 */

class FWScript;

typedef int (FWScript::*opFunc)();

struct Opcode {
      const opFunc proc;
      const char *args;
};

/*! \brief Fixed size array for script variables
 */
00056 class ScriptVars {
private:
00058       unsigned int _size; ///< Size of array
00059       int16 *_vars; ///< Variable values

public:
      // Explicit to prevent var=0 instead of var[i]=0 typos.
      explicit ScriptVars(unsigned int len = 50);
      ScriptVars(Common::SeekableReadStream &fHandle, unsigned int len = 50);
      ScriptVars(const ScriptVars &src);
      ~ScriptVars(void);

      ScriptVars &operator=(const ScriptVars &src);
      int16 &operator[](unsigned int idx);
      int16 operator[](unsigned int idx) const;

      void save(Common::OutSaveFile &fHandle) const;
      void save(Common::OutSaveFile &fHandle, unsigned int len) const;
      void load(Common::SeekableReadStream &fHandle);
      void load(Common::SeekableReadStream &fHandle, unsigned int len);
      void reset(void);
};

class FWScriptInfo;

/*! \brief Script bytecode and initial labels, ScriptStruct replacement.
 *
 * _data is one byte longer to make sure strings in bytecode are properly
 * terminated
 */
00086 class RawScript {
private:
00088       byte *_data; ///< Script bytecode
00089       ScriptVars _labels; ///< Initial script labels

protected:
      void computeLabels(const FWScriptInfo &info);
      int getNextLabel(const FWScriptInfo &info, int offset) const;

public:
00096       uint16 _size; ///< Bytecode length

      explicit RawScript(uint16 size);
      RawScript(const FWScriptInfo &info, const byte *data, uint16 size);
      RawScript(const RawScript &src);
      ~RawScript(void);

      RawScript &operator=(const RawScript &src);

      void setData(const FWScriptInfo &info, const byte *data);
      /*! \brief Size of script
       * \return Size of script
       */
      const ScriptVars &labels(void) const;
      byte getByte(unsigned int pos) const;
      uint16 getWord(unsigned int pos) const;
      const char *getString(unsigned int pos) const;
      uint16 getLabel(const FWScriptInfo &info, byte index, uint16 offset) const;
};

/*! \brief Object script class, RelObjectScript replacement
 *
 * Script parameters are not used, this class is required by different
 * script initialization of object scripts
 */
00121 class RawObjectScript : public RawScript {
public:
00123       int16 _runCount; ///< How many times the script was used
00124       uint16 _param1; ///< Additional parameter not used at the moment
00125       uint16 _param2; ///< Additional parameter not used at the moment
00126       uint16 _param3; ///< Additional parameter not used at the moment

      RawObjectScript(uint16 size, uint16 p1, uint16 p2, uint16 p3);
      RawObjectScript(const FWScriptInfo &info, const byte *data, uint16 size, uint16 p1, uint16 p2, uint16 p3);

      /// \brief Run the script one more time
      /// \return Run count before incrementation
00133       int16 run(void) { return _runCount++; }
};

/*! \brief Future Wars script, prcLinkedListStruct replacement
 * \todo Rewrite _globalVars initialization
 */
00139 class FWScript {
private:
00141       const RawScript &_script; ///< Script bytecode reference
00142       uint16 _pos; ///< Current position in script
00143       uint16 _line; ///< Current opcode index in bytecode for debugging
00144       uint16 _compare; ///< Last compare result
00145       ScriptVars _labels; ///< Current script labels
00146       ScriptVars _localVars; ///< Local script variables
00147       ScriptVars &_globalVars; ///< Global variables reference
00148       FWScriptInfo *_info; ///< Script info

protected:
      static const Opcode *_opcodeTable;
      static unsigned int _numOpcodes;

      int o1_modifyObjectParam();
      int o1_getObjectParam();
      int o1_addObjectParam();
      int o1_subObjectParam();
      int o1_mulObjectParam();
      int o1_divObjectParam();
      int o1_compareObjectParam();
      int o1_setupObject();
      int o1_checkCollision();
      int o1_loadVar();
      int o1_addVar();
      int o1_subVar();
      int o1_mulVar();
      int o1_divVar();
      int o1_compareVar();
      int o1_modifyObjectParam2();
      int o1_loadMask0();
      int o1_unloadMask0();
      int o1_addToBgList();
      int o1_loadMask1();
      int o1_unloadMask1();
      int o1_loadMask4();
      int o1_unloadMask4();
      int o1_addSpriteFilledToBgList();
      int o1_op1B();
      int o1_label();
      int o1_goto();
      int o1_gotoIfSup();
      int o1_gotoIfSupEqu();
      int o1_gotoIfInf();
      int o1_gotoIfInfEqu();
      int o1_gotoIfEqu();
      int o1_gotoIfDiff();
      int o1_removeLabel();
      int o1_loop();
      int o1_startGlobalScript();
      int o1_endGlobalScript();
      int o1_loadAnim();
      int o1_loadBg();
      int o1_loadCt();
      int o1_loadPart();
      int o1_closePart();
      int o1_loadNewPrcName();
      int o1_requestCheckPendingDataLoad();
      int o1_blitAndFade();
      int o1_fadeToBlack();
      int o1_transformPaletteRange();
      int o1_setDefaultMenuBgColor();
      int o1_palRotate();
      int o1_break();
      int o1_endScript();
      int o1_message();
      int o1_loadGlobalVar();
      int o1_compareGlobalVar();
      int o1_declareFunctionName();
      int o1_freePartRange();
      int o1_unloadAllMasks();
      int o1_setScreenDimensions();
      int o1_displayBackground();
      int o1_initializeZoneData();
      int o1_setZoneDataEntry();
      int o1_getZoneDataEntry();
      int o1_setPlayerCommandPosY();
      int o1_allowPlayerInput();
      int o1_disallowPlayerInput();
      int o1_changeDataDisk();
      int o1_loadMusic();
      int o1_playMusic();
      int o1_fadeOutMusic();
      int o1_stopSample();
      int o1_op71();
      int o1_op72();
      int o1_op73();
      int o1_playSample();
      int o1_disableSystemMenu();
      int o1_loadMask5();
      int o1_unloadMask5();

      // pointers to member functions in C++ suck...
      int o2_loadCt();
      int o2_loadPart();
      int o2_addSeqListElement();
      int o2_removeSeq();
      int o2_playSample();
      int o2_playSampleAlt();
      int o2_op81();
      int o2_modifySeqListElement();
      int o2_isSeqRunning();
      int o2_gotoIfSupNearest();
      int o2_gotoIfSupEquNearest();
      int o2_gotoIfInfNearest();
      int o2_gotoIfInfEquNearest();
      int o2_gotoIfEquNearest();
      int o2_gotoIfDiffNearest();
      int o2_startObjectScript();
      int o2_stopObjectScript();
      int o2_op8D();
      int o2_addBackground();
      int o2_removeBackground();
      int o2_loadAbs();
      int o2_loadBg();
      int o2_wasZoneChecked();
      int o2_op9B();
      int o2_op9C();
      int o2_useBgScroll();
      int o2_setAdditionalBgVScroll();
      int o2_op9F();
      int o2_addGfxElementType20();
      int o2_removeGfxElementType20();
      int o2_addGfxElementType21();
      int o2_removeGfxElementType21();
      int o2_loadMask22();
      int o2_unloadMask22();

      byte getNextByte();
      uint16 getNextWord();
      const char *getNextString();

      void load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos);

      FWScript(const RawScript &script, int16 index, FWScriptInfo *info);
      FWScript(RawObjectScript &script, int16 index, FWScriptInfo *info);
      FWScript(const FWScript &src, FWScriptInfo *info);

public:
00279       int16 _index; ///< Index in script table

      static void setupTable();

      FWScript(const RawScript &script, int16 index);
//    FWScript(const RawObjectScript &script, int16 index);
      FWScript(const FWScript &src);
      ~FWScript(void);

      int execute();
      void save(Common::OutSaveFile &fHandle) const;

      friend class FWScriptInfo;

      // workaround for bug in g++ which prevents protected member functions
      // of FWScript from being used in OSScript::_opcodeTable[]
      // initialization ("error: protected within this context")
      friend class OSScript;
};

/*! \brief Operation Stealth script, prcLinkedListStruct replacement
 */
00301 class OSScript : public FWScript {
private:
      static const Opcode *_opcodeTable;
      static unsigned int _numOpcodes;

protected:
      void load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos);

public:
      static void setupTable();

      OSScript(const RawScript &script, int16 index);
      OSScript(RawObjectScript &script, int16 index);
      OSScript(const OSScript &src);

      friend class OSScriptInfo;
};

/*! \brief Future Wars script factory and info
 */
00321 class FWScriptInfo {
protected:
      virtual opFunc opcodeHandler(byte opcode) const;

public:
      virtual ~FWScriptInfo() {}

      virtual const char *opcodeInfo(byte opcode) const;
      virtual FWScript *create(const RawScript &script, int16 index) const;
      virtual FWScript *create(const RawObjectScript &script, int16 index) const;
      virtual FWScript *create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const;
      virtual FWScript *create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const;

      friend class FWScript;
};

/*! \brief Operation Stealth script factory and info
 */
00339 class OSScriptInfo : public FWScriptInfo {
protected:
      virtual opFunc opcodeHandler(byte opcode) const;

public:
      virtual ~OSScriptInfo() {}

      virtual const char *opcodeInfo(byte opcode) const;
      virtual FWScript *create(const RawScript &script, int16 index) const;
      virtual FWScript *create(const RawObjectScript &script, int16 index) const;
      virtual FWScript *create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const;
      virtual FWScript *create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const;

      friend class FWScript;
};

typedef Common::SharedPtr<FWScript> ScriptPtr;
typedef Common::SharedPtr<RawScript> RawScriptPtr;
typedef Common::SharedPtr<RawObjectScript> RawObjectScriptPtr;
typedef Common::List<ScriptPtr> ScriptList;
typedef Common::Array<RawScriptPtr> RawScriptArray;
typedef Common::Array<RawObjectScriptPtr> RawObjectScriptArray;

#define NUM_MAX_SCRIPT 50

extern RawScriptArray scriptTable;
extern FWScriptInfo *scriptInfo;
extern ScriptVars globalVars;

void setupOpcodes();

void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx);
void dumpScript(char *dumpName);

#define OP_loadPart                     0x3F
#define OP_loadNewPrcName               0x41
#define OP_requestCheckPendingDataLoad  0x42
#define OP_endScript                    0x50

void addScriptToGlobalScripts(uint16 idx);
int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx);

void runObjectScript(int16 entryIdx);

void executeObjectScripts(void);
void executeGlobalScripts(void);

void purgeObjectScripts(void);
void purgeGlobalScripts(void);

} // End of namespace Cine

#endif

Generated by  Doxygen 1.6.0   Back to index