aboutsummaryrefslogtreecommitdiff
path: root/engines/cine/script.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cine/script.h')
-rw-r--r--engines/cine/script.h428
1 files changed, 304 insertions, 124 deletions
diff --git a/engines/cine/script.h b/engines/cine/script.h
index b6f3c79219..4bcf4b6ccb 100644
--- a/engines/cine/script.h
+++ b/engines/cine/script.h
@@ -27,17 +27,39 @@
#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 {
+ opFunc proc;
+ const char *args;
+};
+
+/*! \brief Fixed size array for script variables
+ */
class ScriptVars {
private:
- unsigned int _size;
- int16 *_vars;
+ unsigned int _size; ///< Size of array
+ int16 *_vars; ///< Variable values
public:
+ // Explicit to prevent var=0 instead of var[i]=0 typos.
explicit ScriptVars(unsigned int len = 50);
ScriptVars(Common::InSaveFile &fHandle, unsigned int len = 50);
ScriptVars(const ScriptVars &src);
@@ -47,26 +69,298 @@ public:
int16 &operator[](unsigned int idx);
int16 operator[](unsigned int idx) const;
- void save(Common::OutSaveFile &fHandle);
- void save(Common::OutSaveFile &fHandle, unsigned int len);
+ void save(Common::OutSaveFile &fHandle) const;
+ void save(Common::OutSaveFile &fHandle, unsigned int len) const;
void load(Common::InSaveFile &fHandle);
void load(Common::InSaveFile &fHandle, unsigned int len);
void reset(void);
};
-struct ScriptStruct {
- byte *ptr;
- uint16 size;
- int16 stack[SCRIPT_STACK_SIZE];
+class FWScriptInfo;
+
+/*! \brief Script bytecode and initial labels, ScriptStruct replacement.
+ *
+ * _data is one byte longer to make sure strings in bytecode are properly
+ * terminated
+ */
+class RawScript {
+private:
+ byte *_data; ///< Script bytecode
+ ScriptVars _labels; ///< Initial script labels
+
+protected:
+ void computeLabels(const FWScriptInfo &info);
+ int getNextLabel(const FWScriptInfo &info, int offset) const;
+
+public:
+ 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
+ */
+class RawObjectScript : public RawScript {
+public:
+ int16 _runCount; ///< How many times the script was used
+ uint16 _param1; ///< Additional parameter not used at the moment
+ uint16 _param2; ///< Additional parameter not used at the moment
+ 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
+ int16 run(void) { return _runCount++; }
};
+/*! \brief Future Wars script, prcLinkedListStruct replacement
+ * \todo Rewrite _globalVars initialization
+ */
+class FWScript {
+private:
+ const RawScript &_script; ///< Script bytecode reference
+ uint16 _pos; ///< Current position in script
+ uint16 _line; ///< Current opcode index in bytecode for debugging
+ uint16 _compare; ///< Last compare result
+ ScriptVars _labels; ///< Current script labels
+ ScriptVars _localVars; ///< Local script variables
+ ScriptVars &_globalVars; ///< Global variables reference
+ FWScriptInfo *_info; ///< Script info
+
+ static const Opcode _opcodeTable[];
+ static const unsigned int _numOpcodes;
+
+protected:
+ int o1_modifyObjectParam();
+ int o1_getObjectParam();
+ int o1_addObjectParam();
+ int o1_subObjectParam();
+ int o1_add2ObjectParam();
+ int o1_sub2ObjectParam();
+ 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_setDefaultMenuColor2();
+ 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_setDefaultMenuColor();
+ 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_loadPart();
+ int o2_addSeqListElement();
+ int o2_removeSeq();
+ int o2_playSample();
+ int o2_playSampleAlt();
+ int o2_op81();
+ int o2_op82();
+ 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_addGfxElementA0();
+ int o2_removeGfxElementA0();
+ int o2_opA2();
+ int o2_opA3();
+ 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:
+ int16 _index; ///< Index in script table
+
+ 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
+ */
+class OSScript : public FWScript {
+private:
+ static const Opcode _opcodeTable[];
+ static const unsigned int _numOpcodes;
+
+protected:
+ void load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos);
+
+public:
+ 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
+ */
+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
+ */
+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 ScriptStruct scriptTable[NUM_MAX_SCRIPT];
+extern RawScriptArray scriptTable;
+extern FWScriptInfo *scriptInfo;
void setupOpcodes();
-void computeScriptStack(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize);
void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx);
void dumpScript(char *dumpName);
@@ -79,7 +373,6 @@ void addScriptToList0(uint16 idx);
int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx);
void runObjectScript(int16 entryIdx);
-int16 stopObjectScript(int16 entryIdx);
void executeList1(void);
void executeList0(void);
@@ -87,119 +380,6 @@ void executeList0(void);
void purgeList1(void);
void purgeList0(void);
-void o1_modifyObjectParam();
-void o1_getObjectParam();
-void o1_addObjectParam();
-void o1_subObjectParam();
-void o1_add2ObjectParam();
-void o1_sub2ObjectParam();
-void o1_compareObjectParam();
-void o1_setupObject();
-void o1_checkCollision();
-void o1_loadVar();
-void o1_addVar();
-void o1_subVar();
-void o1_mulVar();
-void o1_divVar();
-void o1_compareVar();
-void o1_modifyObjectParam2();
-void o1_loadMask0();
-void o1_unloadMask0();
-void o1_addToBgList();
-void o1_loadMask1();
-void o1_unloadMask1();
-void o1_loadMask4();
-void o1_unloadMask4();
-void o1_addSpriteFilledToBgList();
-void o1_op1B();
-void o1_label();
-void o1_goto();
-void o1_gotoIfSup();
-void o1_gotoIfSupEqu();
-void o1_gotoIfInf();
-void o1_gotoIfInfEqu();
-void o1_gotoIfEqu();
-void o1_gotoIfDiff();
-void o1_removeLabel();
-void o1_loop();
-void o1_startGlobalScript();
-void o1_endGlobalScript();
-void o1_loadAnim();
-void o1_loadBg();
-void o1_loadCt();
-void o1_loadPart();
-void o1_closePart();
-void o1_loadNewPrcName();
-void o1_requestCheckPendingDataLoad();
-void o1_blitAndFade();
-void o1_fadeToBlack();
-void o1_transformPaletteRange();
-void o1_setDefaultMenuColor2();
-void o1_palRotate();
-void o1_break();
-void o1_endScript();
-void o1_message();
-void o1_loadGlobalVar();
-void o1_compareGlobalVar();
-void o1_declareFunctionName();
-void o1_freePartRange();
-void o1_unloadAllMasks();
-void o1_setScreenDimensions();
-void o1_displayBackground();
-void o1_initializeZoneData();
-void o1_setZoneDataEntry();
-void o1_getZoneDataEntry();
-void o1_setDefaultMenuColor();
-void o1_allowPlayerInput();
-void o1_disallowPlayerInput();
-void o1_changeDataDisk();
-void o1_loadMusic();
-void o1_playMusic();
-void o1_fadeOutMusic();
-void o1_stopSample();
-void o1_op71();
-void o1_op72();
-void o1_op73();
-void o1_playSample();
-void o1_playSample();
-void o1_disableSystemMenu();
-void o1_loadMask5();
-void o1_unloadMask5();
-
-void o2_loadPart();
-void o2_addSeqListElement();
-void o2_removeSeq();
-void o2_playSample();
-void o2_playSampleAlt();
-void o2_op81();
-void o2_op82();
-void o2_isSeqRunning();
-void o2_gotoIfSupNearest();
-void o2_gotoIfSupEquNearest();
-void o2_gotoIfInfNearest();
-void o2_gotoIfInfEquNearest();
-void o2_gotoIfEquNearest();
-void o2_gotoIfDiffNearest();
-void o2_startObjectScript();
-void o2_stopObjectScript();
-void o2_op8D();
-void o2_addBackground();
-void o2_removeBackground();
-void o2_loadAbs();
-void o2_loadBg();
-void o2_wasZoneChecked();
-void o2_op9B();
-void o2_op9C();
-void o2_useBgScroll();
-void o2_setAdditionalBgVScroll();
-void o2_op9F();
-void o2_addGfxElementA0();
-void o2_opA1();
-void o2_opA2();
-void o2_opA3();
-void o2_loadMask22();
-void o2_unloadMask22();
-
} // End of namespace Cine
#endif