ScummVM API documentation
vm.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#ifndef SCI_ENGINE_VM_H
23#define SCI_ENGINE_VM_H
24
25/* VM and kernel declarations */
26
27#include "sci/engine/vm_types.h" // for reg_t
28#include "sci/resource/resource.h" // for SciVersion
29
30#include "common/util.h"
31
32namespace Sci {
33
34class SegManager;
35struct EngineState;
36class Object;
37class ResourceManager;
38class Script;
39
41#define VM_STACK_SIZE 0x1000
42
44#define SCRIPT_OBJECT_MAGIC_NUMBER 0x1234
45
47#define SCRIPT_OBJECT_MAGIC_OFFSET (getSciVersion() < SCI_VERSION_1_1 ? -8 : 0)
48
50#define CALL_SP_CARRY NULL
51
54 kSelectorNone = 0,
55 kSelectorVariable,
56 kSelectorMethod
57};
58
59struct Class {
60 int script;
62};
63
64// A reference to an object's variable.
65// The object is stored as a reg_t, the variable as an index into _variables
66struct ObjVarRef {
67 reg_t obj;
68 int varindex;
69
70 reg_t* getPointer(SegManager *segMan) const;
71};
72
73enum ExecStackType {
74 EXEC_STACK_TYPE_CALL = 0,
75 EXEC_STACK_TYPE_KERNEL = 1,
76 EXEC_STACK_TYPE_VARSELECTOR = 2
77};
78
79struct ExecStack {
82
83 union {
84 ObjVarRef varp; // Variable pointer for r/w access
85 reg_t pc; // Pointer to the initial program counter. Not accurate for the TOS element
86 } addr;
87
88 StackPtr fp; // Frame pointer
89 StackPtr sp; // Stack pointer
90
91 int argc;
92 StackPtr variables_argp; // Argument pointer
93
94 int tempCount; // Number of temp variables allocated by link opcode
95
96 SegmentId local_segment; // local variables etc
97
98 Selector debugSelector; // The selector which was used to call or -1 if not applicable
99 int debugExportId; // The exportId which was called or -1 if not applicable
100 int debugLocalCallOffset; // Local call offset or -1 if not applicable
101 int debugOrigin; // The stack frame position the call was made from, or -1 if it was the initial call
102 int debugKernelFunction; // The kernel function called, or -1 if not applicable
103 int debugKernelSubFunction; // The kernel subfunction called, or -1 if not applicable
104 ExecStackType type;
105
106 reg_t* getVarPointer(SegManager *segMan) const;
107
108 ExecStack(reg_t objp_, reg_t sendp_, StackPtr sp_, int argc_, StackPtr argp_,
109 SegmentId localsSegment_, reg_t pc_, Selector debugSelector_,
110 int debugKernelFunction_, int debugKernelSubFunction_,
111 int debugExportId_, int debugLocalCallOffset_, int debugOrigin_,
112 ExecStackType type_) {
113 objp = objp_;
114 sendp = sendp_;
115 // varp is set separately for varselector calls
116 addr.pc = pc_;
117 fp = sp = sp_;
118 argc = argc_;
119 variables_argp = argp_;
120 tempCount = 0;
121 if (localsSegment_ != kUninitializedSegment)
122 local_segment = localsSegment_;
123 else
124 local_segment = pc_.getSegment();
125 debugSelector = debugSelector_;
126 debugKernelFunction = debugKernelFunction_;
127 debugKernelSubFunction = debugKernelSubFunction_;
128 debugExportId = debugExportId_;
129 debugLocalCallOffset = debugLocalCallOffset_;
130 debugOrigin = debugOrigin_;
131 type = type_;
132 }
133};
134
135enum {
136 VAR_GLOBAL = 0,
137 VAR_LOCAL = 1,
138 VAR_TEMP = 2,
139 VAR_PARAM = 3
140};
141
142enum GlobalVar {
143 kGlobalVarEgo = 0,
144 kGlobalVarGame = 1,
145 kGlobalVarCurrentRoom = 2,
146 kGlobalVarSpeed = 3, // SCI16
147 kGlobalVarQuit = 4,
148 kGlobalVarCast = 5,
149 kGlobalVarSounds = 8,
150 kGlobalVarPlanes = 10, // SCI32
151 kGlobalVarCurrentRoomNo = 11,
152 kGlobalVarPreviousRoomNo = 12,
153 kGlobalVarNewRoomNo = 13,
154 kGlobalVarScore = 15,
155 kGlobalVarVersionNew = 27, // version string or object in later games
156 kGlobalVarVersionOld = 28, // version string in earlier games
157 kGlobalVarGK2MusicVolume = 76, // 0 to 127
158 kGlobalVarPhant2SecondaryVolume = 76, // 0 to 127
159 kGlobalVarUser = 80,
160 kGlobalVarFastCast = 84, // SCI16
161 kGlobalVarMessageType = 90,
162 kGlobalVarTextSpeed = 94, // SCI32; 0 is fastest, 8 is slowest
163 kGlobalVarGK1Music1 = 102, // 0 to 127
164 kGlobalVarGK1Music2 = 103, // 0 to 127
165 kGlobalVarRamaCatalogFile = 130,
166 kGlobalVarLSL6HiresGameFlags = 137,
167 kGlobalVarKQ7UpscaleVideos = 160,
168 kGlobalVarGK1NarratorMode = 166, // 0 for text, 1 for speech
169 kGlobalVarRamaMusicVolume = 176, // 0 to 16
170 kGlobalVarPhant1MusicVolume = 187, // 0 to 15
171 kGlobalVarPhant1DACVolume = 188, // 0 to 127
172 kGlobalVarLSL6MusicVolume = 194, // 0 to 13
173 kGlobalVarGK1DAC1 = 207, // 0 to 127
174 kGlobalVarPhant2CensorshipFlag = 207,
175 kGlobalVarGK1DAC2 = 208, // 0 to 127
176 kGlobalVarLSL6HiresRestoreTextWindow = 210,
177 kGlobalVarGK1DAC3 = 211, // 0 to 127
178 kGlobalVarShiversFlags = 211,
179 kGlobalVarTorinMusicVolume = 227, // 0 to 100
180 kGlobalVarTorinSFXVolume = 228, // 0 to 100
181 kGlobalVarTorinSpeechVolume = 229, // 0 to 100
182 // Phant2 labels its volume slider as "music volume" but it is actually
183 // a master volume that affects both music *and* sound effects
184 kGlobalVarPhant2MasterVolume = 236, // 0 to 127
185 kGlobalVarPhant2ControlPanel = 250,
186 kGlobalVarShivers1Score = 349,
187 kGlobalVarQFG4Flags = 500,
188 kGlobalVarHoyle5MusicVolume = 897
189};
190
192enum {
193 GC_INTERVAL = 0x8000
194};
195
196enum SciOpcodes {
197 op_bnot = 0x00, // 000
198 op_add = 0x01, // 001
199 op_sub = 0x02, // 002
200 op_mul = 0x03, // 003
201 op_div = 0x04, // 004
202 op_mod = 0x05, // 005
203 op_shr = 0x06, // 006
204 op_shl = 0x07, // 007
205 op_xor = 0x08, // 008
206 op_and = 0x09, // 009
207 op_or = 0x0a, // 010
208 op_neg = 0x0b, // 011
209 op_not = 0x0c, // 012
210 op_eq_ = 0x0d, // 013
211 op_ne_ = 0x0e, // 014
212 op_gt_ = 0x0f, // 015
213 op_ge_ = 0x10, // 016
214 op_lt_ = 0x11, // 017
215 op_le_ = 0x12, // 018
216 op_ugt_ = 0x13, // 019
217 op_uge_ = 0x14, // 020
218 op_ult_ = 0x15, // 021
219 op_ule_ = 0x16, // 022
220 op_bt = 0x17, // 023
221 op_bnt = 0x18, // 024
222 op_jmp = 0x19, // 025
223 op_ldi = 0x1a, // 026
224 op_push = 0x1b, // 027
225 op_pushi = 0x1c, // 028
226 op_toss = 0x1d, // 029
227 op_dup = 0x1e, // 030
228 op_link = 0x1f, // 031
229 op_call = 0x20, // 032
230 op_callk = 0x21, // 033
231 op_callb = 0x22, // 034
232 op_calle = 0x23, // 035
233 op_ret = 0x24, // 036
234 op_send = 0x25, // 037
235 op_info = 0x26, // 038
236 op_superP = 0x27, // 039
237 op_class = 0x28, // 040
238 // dummy 0x29, // 041
239 op_self = 0x2a, // 042
240 op_super = 0x2b, // 043
241 op_rest = 0x2c, // 044
242 op_lea = 0x2d, // 045
243 op_selfID = 0x2e, // 046
244 // dummy 0x2f // 047
245 op_pprev = 0x30, // 048
246 op_pToa = 0x31, // 049
247 op_aTop = 0x32, // 050
248 op_pTos = 0x33, // 051
249 op_sTop = 0x34, // 052
250 op_ipToa = 0x35, // 053
251 op_dpToa = 0x36, // 054
252 op_ipTos = 0x37, // 055
253 op_dpTos = 0x38, // 056
254 op_lofsa = 0x39, // 057
255 op_lofss = 0x3a, // 058
256 op_push0 = 0x3b, // 059
257 op_push1 = 0x3c, // 060
258 op_push2 = 0x3d, // 061
259 op_pushSelf = 0x3e, // 062
260 op_line = 0x3f, // 063
261 //
262 op_lag = 0x40, // 064
263 op_lal = 0x41, // 065
264 op_lat = 0x42, // 066
265 op_lap = 0x43, // 067
266 op_lsg = 0x44, // 068
267 op_lsl = 0x45, // 069
268 op_lst = 0x46, // 070
269 op_lsp = 0x47, // 071
270 op_lagi = 0x48, // 072
271 op_lali = 0x49, // 073
272 op_lati = 0x4a, // 074
273 op_lapi = 0x4b, // 075
274 op_lsgi = 0x4c, // 076
275 op_lsli = 0x4d, // 077
276 op_lsti = 0x4e, // 078
277 op_lspi = 0x4f, // 079
278 //
279 op_sag = 0x50, // 080
280 op_sal = 0x51, // 081
281 op_sat = 0x52, // 082
282 op_sap = 0x53, // 083
283 op_ssg = 0x54, // 084
284 op_ssl = 0x55, // 085
285 op_sst = 0x56, // 086
286 op_ssp = 0x57, // 087
287 op_sagi = 0x58, // 088
288 op_sali = 0x59, // 089
289 op_sati = 0x5a, // 090
290 op_sapi = 0x5b, // 091
291 op_ssgi = 0x5c, // 092
292 op_ssli = 0x5d, // 093
293 op_ssti = 0x5e, // 094
294 op_sspi = 0x5f, // 095
295 //
296 op_plusag = 0x60, // 096
297 op_plusal = 0x61, // 097
298 op_plusat = 0x62, // 098
299 op_plusap = 0x63, // 099
300 op_plussg = 0x64, // 100
301 op_plussl = 0x65, // 101
302 op_plusst = 0x66, // 102
303 op_plussp = 0x67, // 103
304 op_plusagi = 0x68, // 104
305 op_plusali = 0x69, // 105
306 op_plusati = 0x6a, // 106
307 op_plusapi = 0x6b, // 107
308 op_plussgi = 0x6c, // 108
309 op_plussli = 0x6d, // 109
310 op_plussti = 0x6e, // 110
311 op_plusspi = 0x6f, // 111
312 //
313 op_minusag = 0x70, // 112
314 op_minusal = 0x71, // 113
315 op_minusat = 0x72, // 114
316 op_minusap = 0x73, // 115
317 op_minussg = 0x74, // 116
318 op_minussl = 0x75, // 117
319 op_minusst = 0x76, // 118
320 op_minussp = 0x77, // 119
321 op_minusagi = 0x78, // 120
322 op_minusali = 0x79, // 121
323 op_minusati = 0x7a, // 122
324 op_minusapi = 0x7b, // 123
325 op_minussgi = 0x7c, // 124
326 op_minussli = 0x7d, // 125
327 op_minussti = 0x7e, // 126
328 op_minusspi = 0x7f // 127
329};
330
331void script_adjust_opcode_formats();
332
346ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct,
347 StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp);
348
349
367 StackPtr sp, int framesize, StackPtr argp);
368
369
377
398SelectorType lookupSelector(SegManager *segMan, reg_t obj, Selector selectorid,
399 ObjVarRef *varp, reg_t *fptr);
400
417int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4]);
418
427uint32 findOffset(const int16 relOffset, const Script *scr, const uint32 pcOffset);
428
429} // End of namespace Sci
430
431#endif // SCI_ENGINE_VM_H
Definition: script.h:71
Definition: seg_manager.h:48
Definition: console.h:28
void run_vm(EngineState *s)
uint32 findOffset(const int16 relOffset, const Script *scr, const uint32 pcOffset)
int readPMachineInstruction(const byte *src, byte &extOpcode, int16 opparams[4])
SelectorType lookupSelector(SegManager *segMan, reg_t obj, Selector selectorid, ObjVarRef *varp, reg_t *fptr)
ExecStack * execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp)
SelectorType
Definition: vm.h:53
ExecStack * send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPtr sp, int framesize, StackPtr argp)
Definition: vm.h:59
reg_t reg
offset; script-relative offset, segment: 0 if not instantiated
Definition: vm.h:61
int script
number of the script the class is in, -1 for non-existing
Definition: vm.h:60
Definition: state.h:100
Definition: vm.h:79
reg_t sendp
Pointer to the object containing the invoked method.
Definition: vm.h:81
reg_t objp
Pointer to the beginning of the current object.
Definition: vm.h:80
Definition: vm.h:66
Definition: vm_types.h:39