ScummVM API documentation
script.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  *
21  * This file is dual-licensed.
22  * In addition to the GPLv3 license mentioned above, MojoTouch has
23  * exclusively licensed this code on March 23th, 2024, to be used in
24  * closed-source products.
25  * Therefore, any contributions (commits) to it will also be dual-licensed.
26  *
27  */
28 
29 #ifndef TOON_SCRIPT_H
30 #define TOON_SCRIPT_H
31 
32 #include "common/stream.h"
33 #include "common/array.h"
34 #include "common/func.h"
35 #include "common/formats/iff_container.h"
36 
37 // Based on Kyra script interpretor
38 namespace Toon {
39 
40 struct EMCState;
41 class ScriptFunc;
43 
44 struct EMCData {
45  char filename[13];
46 
47  byte *text;
48  uint16 *data;
49  uint16 *ordr;
50  uint16 dataSize;
51 
52  const Common::Array<const OpcodeV2 *> *sysFuncs;
53 };
54 
55 struct EMCState {
56  enum {
57  kStackSize = 100,
58  kStackLastEntry = kStackSize - 1
59  };
60 
61  const uint16 *ip;
62  const EMCData *dataPtr;
63  int16 retValue;
64  uint16 bp;
65  uint16 sp;
66  int16 regs[30]; // VM registers
67  int16 stack[kStackSize]; // VM stack
68  bool running;
69 };
70 
71 #define stackPos(x) (state->stack[state->sp+x])
72 #define stackPosString(x) ((const char *)&state->dataPtr->text[READ_BE_UINT16(&state->dataPtr->text[stackPos(x)<<1])])
73 
74 class Resource;
75 class ToonEngine;
76 
77 class IFFParser : public Common::IFFParser {
78 public:
80  // It seems Westwood missunderstood the 'size' field of the FORM chunk.
81  //
82  // For EMC scripts (type EMC2) it's filesize instead of filesize - 8,
83  // means accidentally including the 8 bytes used by the chunk header for the FORM
84  // chunk.
85  //
86  // For TIM scripts (type AVFS) it's filesize - 12 instead of filesize - 8,
87  // means it will not include the size of the 'type' field in the FORM chunk,
88  // instead of only not including the chunk header size.
89  //
90  // Both lead to some problems in our IFF parser, either reading after the end
91  // of file or producing a "Chunk overread" error message. To work around this
92  // we need to adjust the size field properly.
93  if (_formType == MKTAG('E','M','C','2'))
94  _formChunk.size -= 8;
95  else if (_formType == MKTAG('A','V','F','S'))
96  _formChunk.size += 4;
97  }
98 };
99 
101 public:
103  ~EMCInterpreter();
104 
105  bool load(const char *filename, EMCData *data, const Common::Array<const OpcodeV2 *> *opcodes);
106  void unload(EMCData *data);
107 
108  void init(EMCState *scriptState, const EMCData *data);
109  bool start(EMCState *script, int function);
110 
111  void saveState(EMCState *script, Common::WriteStream *stream);
112  void loadState(EMCState *script, Common::ReadStream *stream);
113 
114  bool isValid(EMCState *script);
115 
116  bool run(EMCState *script);
117 protected:
118  ToonEngine *_vm;
119  int16 _parameter;
120 
121  const char *_filename;
122  EMCData *_scriptData;
123 
124  bool callback(Common::IFFChunk &chunk);
125 
126  typedef void (EMCInterpreter::*OpcodeProc)(EMCState *);
127  struct OpcodeEntry {
128  OpcodeProc proc;
129  const char *desc;
130  };
131 
132  const OpcodeEntry *_opcodes;
133 private:
134  void op_jmp(EMCState *);
135  void op_setRetValue(EMCState *);
136  void op_pushRetOrPos(EMCState *);
137  void op_push(EMCState *);
138  void op_pushReg(EMCState *);
139  void op_pushBPNeg(EMCState *);
140  void op_pushBPAdd(EMCState *);
141  void op_popRetOrPos(EMCState *);
142  void op_popReg(EMCState *);
143  void op_popBPNeg(EMCState *);
144  void op_popBPAdd(EMCState *);
145  void op_addSP(EMCState *);
146  void op_subSP(EMCState *);
147  void op_sysCall(EMCState *);
148  void op_ifNotJmp(EMCState *);
149  void op_negate(EMCState *);
150  void op_eval(EMCState *);
151  void op_setRetAndJmp(EMCState *);
152 };
153 
154 } // End of namespace Toon
155 
156 #endif
Definition: stream.h:77
Definition: array.h:52
Definition: script.h:44
Definition: toon.h:118
Definition: script.h:127
Definition: iff_container.h:173
Definition: func.h:452
#define MKTAG(a0, a1, a2, a3)
Definition: endian.h:188
Definition: stream.h:385
Definition: anim.h:39
Definition: script.h:55
Definition: iff_container.h:160
Definition: script.h:77
Definition: script.h:100