ScummVM API documentation
exec.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 
22 
23 #ifndef PARALLACTION_EXEC_H
24 #define PARALLACTION_EXEC_H
25 
26 #include "common/util.h"
27 #include "parallaction/objects.h"
28 
29 
30 namespace Parallaction {
31 
32 class Parallaction_ns;
33 class Parallaction_br;
34 
35 /* NOTE: CommandExec and ProgramExec perform similar tasks on different data.
36  CommandExec executes commands found in location scripts, while ProgramExec
37  runs animation programs.
38 
39  The main difference is how suspension is handled. CommandExec is coded with
40  the assumption that there may be at most one suspended list of commands at any
41  moment, and thus stores the suspended context itself. It also offers a
42  runSuspended() routine that resumes execution on request.
43  ProgramExec instead stores the suspension information in the programs themselves.
44  Programs are in fact meant to be run (almost) regularly on each frame .
45  */
46 
48  CommandPtr _cmd;
49  ZonePtr _z;
50 
51  // TODO: add a way to invoke CommandExec::suspend() from the context. With that
52  // in place, opcodes dependency on CommandExec would be zero, and they could
53  // be moved into a Game object, together with the non-infrastructural code now
54  // in Parallaction_XX
55 };
58 #define DECLARE_UNQUALIFIED_COMMAND_OPCODE(op) void cmdOp_##op(CommandContext &)
59 
61  AnimationPtr _anim;
62  ProgramPtr _program;
63  InstructionPtr _inst;
64  uint32 _ip;
65  uint16 _modCounter;
66  bool _suspend;
67 };
70 #define DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(op) void instOp_##op(ProgramContext &)
71 
72 
73 template<class OpcodeSet>
74 class Exec {
75 protected:
76  OpcodeSet _opcodes;
77  typedef typename OpcodeSet::iterator OpIt;
78 public:
79  virtual ~Exec() {
80  for (OpIt i = _opcodes.begin(); i != _opcodes.end(); ++i)
81  delete *i;
82  _opcodes.clear();
83  }
84 };
85 
86 class CommandExec : public Exec<CommandOpcodeSet> {
87 protected:
88  Parallaction *_vm;
89 
90  CommandContext _ctxt;
91  ZonePtr _execZone;
92  bool _running;
93  bool _suspend;
94 
96  bool _valid;
97  CommandList::iterator _first;
99  ZonePtr _zone;
100  } _suspendedCtxt;
101 
102  void runList(CommandList::iterator first, CommandList::iterator last);
103  void createSuspendList(CommandList::iterator first, CommandList::iterator last);
104  void cleanSuspendedList();
105 public:
107 
108  void run(CommandList &list, ZonePtr z = ZonePtr());
109  void runSuspended();
110  void suspend();
111 };
112 
113 class CommandExec_ns : public CommandExec {
114 protected:
115  Parallaction_ns *_vm;
116 
117  DECLARE_UNQUALIFIED_COMMAND_OPCODE(invalid);
118  DECLARE_UNQUALIFIED_COMMAND_OPCODE(set);
119  DECLARE_UNQUALIFIED_COMMAND_OPCODE(clear);
120  DECLARE_UNQUALIFIED_COMMAND_OPCODE(start);
121  DECLARE_UNQUALIFIED_COMMAND_OPCODE(speak);
122  DECLARE_UNQUALIFIED_COMMAND_OPCODE(get);
123  DECLARE_UNQUALIFIED_COMMAND_OPCODE(location);
124  DECLARE_UNQUALIFIED_COMMAND_OPCODE(open);
125  DECLARE_UNQUALIFIED_COMMAND_OPCODE(close);
126  DECLARE_UNQUALIFIED_COMMAND_OPCODE(on);
127  DECLARE_UNQUALIFIED_COMMAND_OPCODE(off);
128  DECLARE_UNQUALIFIED_COMMAND_OPCODE(call);
129  DECLARE_UNQUALIFIED_COMMAND_OPCODE(toggle);
130  DECLARE_UNQUALIFIED_COMMAND_OPCODE(drop);
131  DECLARE_UNQUALIFIED_COMMAND_OPCODE(quit);
132  DECLARE_UNQUALIFIED_COMMAND_OPCODE(move);
133  DECLARE_UNQUALIFIED_COMMAND_OPCODE(stop);
134 public:
136 };
137 
138 class CommandExec_br : public CommandExec {
139 protected:
140  Parallaction_br *_vm;
141 
142  DECLARE_UNQUALIFIED_COMMAND_OPCODE(invalid);
143  DECLARE_UNQUALIFIED_COMMAND_OPCODE(set);
144  DECLARE_UNQUALIFIED_COMMAND_OPCODE(clear);
145  DECLARE_UNQUALIFIED_COMMAND_OPCODE(speak);
146  DECLARE_UNQUALIFIED_COMMAND_OPCODE(get);
147  DECLARE_UNQUALIFIED_COMMAND_OPCODE(toggle);
148  DECLARE_UNQUALIFIED_COMMAND_OPCODE(quit);
149  DECLARE_UNQUALIFIED_COMMAND_OPCODE(location);
150  DECLARE_UNQUALIFIED_COMMAND_OPCODE(open);
151  DECLARE_UNQUALIFIED_COMMAND_OPCODE(close);
152  DECLARE_UNQUALIFIED_COMMAND_OPCODE(on);
153  DECLARE_UNQUALIFIED_COMMAND_OPCODE(off);
154  DECLARE_UNQUALIFIED_COMMAND_OPCODE(call);
155  DECLARE_UNQUALIFIED_COMMAND_OPCODE(drop);
156  DECLARE_UNQUALIFIED_COMMAND_OPCODE(move);
157  DECLARE_UNQUALIFIED_COMMAND_OPCODE(start);
158  DECLARE_UNQUALIFIED_COMMAND_OPCODE(stop);
159  DECLARE_UNQUALIFIED_COMMAND_OPCODE(character);
160  DECLARE_UNQUALIFIED_COMMAND_OPCODE(followme);
161  DECLARE_UNQUALIFIED_COMMAND_OPCODE(onmouse);
162  DECLARE_UNQUALIFIED_COMMAND_OPCODE(offmouse);
163  DECLARE_UNQUALIFIED_COMMAND_OPCODE(add);
164  DECLARE_UNQUALIFIED_COMMAND_OPCODE(leave);
165  DECLARE_UNQUALIFIED_COMMAND_OPCODE(inc);
166  DECLARE_UNQUALIFIED_COMMAND_OPCODE(dec);
167  DECLARE_UNQUALIFIED_COMMAND_OPCODE(ifeq);
168  DECLARE_UNQUALIFIED_COMMAND_OPCODE(iflt);
169  DECLARE_UNQUALIFIED_COMMAND_OPCODE(ifgt);
170  DECLARE_UNQUALIFIED_COMMAND_OPCODE(let);
171  DECLARE_UNQUALIFIED_COMMAND_OPCODE(music);
172  DECLARE_UNQUALIFIED_COMMAND_OPCODE(fix);
173  DECLARE_UNQUALIFIED_COMMAND_OPCODE(unfix);
174  DECLARE_UNQUALIFIED_COMMAND_OPCODE(zeta);
175  DECLARE_UNQUALIFIED_COMMAND_OPCODE(scroll);
176  DECLARE_UNQUALIFIED_COMMAND_OPCODE(swap);
177  DECLARE_UNQUALIFIED_COMMAND_OPCODE(give);
178  DECLARE_UNQUALIFIED_COMMAND_OPCODE(text);
179  DECLARE_UNQUALIFIED_COMMAND_OPCODE(part);
180  DECLARE_UNQUALIFIED_COMMAND_OPCODE(testsfx);
181  DECLARE_UNQUALIFIED_COMMAND_OPCODE(ret);
182  DECLARE_UNQUALIFIED_COMMAND_OPCODE(onsave);
183  DECLARE_UNQUALIFIED_COMMAND_OPCODE(offsave);
184 public:
186 };
187 
188 
189 
190 
191 class ProgramExec : public Exec<ProgramOpcodeSet> {
192 protected:
193  ProgramContext _ctxt;
194  uint16 _modCounter;
195  const char **_instructionNames;
196 
197  void runScript(ProgramPtr script, AnimationPtr a);
198 public:
199  void runScripts(ProgramList::iterator first, ProgramList::iterator last);
200  ProgramExec();
201 };
202 
203 class ProgramExec_ns : public ProgramExec {
204 protected:
205  Parallaction_ns *_vm;
206 
207  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(invalid);
208  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(on);
209  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(off);
210  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(loop);
211  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endloop);
212  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(show);
213  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(call);
214  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(inc);
215  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(set);
216  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(put);
217  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(wait);
218  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(start);
219  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(sound);
220  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(move);
221  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endscript);
222 public:
224 };
225 
226 class ProgramExec_br : public ProgramExec {
227 protected:
228  Parallaction_br *_vm;
229 
230  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(invalid);
231  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(loop);
232  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endloop);
233  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(show);
234  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(call);
235  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endscript);
236  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(on);
237  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(off);
238  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(inc);
239  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(dec);
240  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(set);
241  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(put);
242  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(wait);
243  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(start);
244  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(process);
245  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(move);
246  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(color);
247  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(mask);
248  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(print);
249  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(text);
250  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(mul);
251  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(div);
252  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(ifeq);
253  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(iflt);
254  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(ifgt);
255  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(endif);
256  DECLARE_UNQUALIFIED_INSTRUCTION_OPCODE(stop);
257 public:
259 };
260 
261 } // namespace Parallaction
262 
263 #endif
Definition: exec.h:60
Definition: exec.h:86
Definition: array.h:52
void clear()
Definition: array.h:280
iterator end()
Definition: array.h:339
iterator begin()
Definition: array.h:334
Definition: exec.h:138
T * iterator
Definition: array.h:54
Definition: parallaction.h:377
Definition: exec.h:226
Definition: debug.h:8
Definition: exec.h:113
Definition: exec.h:74
constexpr remove_reference_t< T > && move(T &&t) noexcept
Definition: util.h:209
Definition: func.h:437
Definition: exec.h:203
Definition: exec.h:191
Definition: list_intern.h:51
Definition: exec.h:47
Definition: parallaction.h:489