ScummVM API documentation
kernel_tables.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_KERNEL_TABLES_H
23 #define SCI_ENGINE_KERNEL_TABLES_H
24 
25 #include "sci/engine/workarounds.h"
26 #include "sci/engine/vm_types.h" // for opcode_formats
27 
28 namespace Sci {
29 
30 // [io] -> either integer or object
31 // (io) -> optionally integer AND an object
32 // (i) -> optional integer
33 // . -> any type
34 // i* -> optional multiple integers
35 // .* -> any parameters afterwards (or none)
36 //
37 // data types:
38 // i - regular integer
39 // o - object
40 // r - reference
41 // l - list
42 // n - node
43 // 0 - NULL
44 // . - any
45 // ! - invalid reference/offset
46 
48  SciVersion fromVersion;
49  SciVersion toVersion;
50 
51  uint16 id;
52 
53  const char *name;
54  KernelFunctionCall *function;
55 
56  const char *signature;
57  const SciWorkaroundEntry *workarounds;
58 };
59 
60 #define SCI_SUBOPENTRY_TERMINATOR { SCI_VERSION_NONE, SCI_VERSION_NONE, 0, NULL, NULL, NULL, NULL }
61 
62 
63 #define SIG_SCIALL SCI_VERSION_NONE, SCI_VERSION_NONE
64 #define SIG_SCI0 SCI_VERSION_NONE, SCI_VERSION_01
65 #define SIG_SCI1 SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE
66 #define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1
67 #define SIG_SINCE_SCI11 SCI_VERSION_1_1, SCI_VERSION_NONE
68 #define SIG_SCI2 SCI_VERSION_2, SCI_VERSION_2
69 #define SIG_SCI21EARLY SCI_VERSION_2_1_EARLY, SCI_VERSION_2_1_EARLY
70 #define SIG_SCI21MID SCI_VERSION_2_1_MIDDLE, SCI_VERSION_2_1_MIDDLE
71 #define SIG_SCI21MID_LATE SCI_VERSION_2_1_MIDDLE, SCI_VERSION_2_1_LATE
72 #define SIG_THRU_SCI21EARLY SCI_VERSION_2, SCI_VERSION_2_1_EARLY
73 #define SIG_THRU_SCI21MID SCI_VERSION_2, SCI_VERSION_2_1_MIDDLE
74 #define SIG_SINCE_SCI21 SCI_VERSION_2_1_EARLY, SCI_VERSION_3
75 #define SIG_SINCE_SCI21MID SCI_VERSION_2_1_MIDDLE, SCI_VERSION_3
76 #define SIG_SINCE_SCI21LATE SCI_VERSION_2_1_LATE, SCI_VERSION_3
77 #define SIG_SCI21LATE SCI_VERSION_2_1_LATE, SCI_VERSION_2_1_LATE
78 #define SIG_SCI3 SCI_VERSION_3, SCI_VERSION_3
79 
80 #define SIG_SCI16 SCI_VERSION_NONE, SCI_VERSION_1_1
81 #define SIG_SCI32 SCI_VERSION_2, SCI_VERSION_NONE
82 
83 // SCI-Sound-Version
84 #define SIG_SOUNDSCI0 SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE
85 #define SIG_SOUNDSCI1EARLY SCI_VERSION_1_EARLY, SCI_VERSION_1_EARLY
86 #define SIG_SOUNDSCI1LATE SCI_VERSION_1_LATE, SCI_VERSION_1_LATE
87 
88 #define SIGFOR_ALL 0x3f
89 #define SIGFOR_DOS 1 << 0
90 #define SIGFOR_PC98 1 << 1
91 #define SIGFOR_WIN 1 << 2
92 #define SIGFOR_MAC 1 << 3
93 #define SIGFOR_AMIGA 1 << 4
94 #define SIGFOR_ATARI 1 << 5
95 #define SIGFOR_PC SIGFOR_DOS|SIGFOR_WIN
96 
97 #define SIG_EVERYWHERE SIG_SCIALL, SIGFOR_ALL
98 
99 #define MAP_CALL(_name_) #_name_, k##_name_
100 #define MAP_EMPTY(_name_) #_name_, kEmpty
101 #define MAP_DUMMY(_name_) #_name_, kDummy
102 
103 // version, subId, function-mapping, signature, workarounds
104 static const SciKernelMapSubEntry kDoSound_subops[] = {
105  { SIG_SOUNDSCI0, 0, MAP_CALL(DoSoundInit), "o", NULL },
106  { SIG_SOUNDSCI0, 1, MAP_CALL(DoSoundPlay), "o", NULL },
107  { SIG_SOUNDSCI0, 2, MAP_EMPTY(DoSoundRestore), "(o)", NULL },
108  { SIG_SOUNDSCI0, 3, MAP_CALL(DoSoundDispose), "o", NULL },
109  { SIG_SOUNDSCI0, 4, MAP_CALL(DoSoundMute), "(i)", NULL },
110  { SIG_SOUNDSCI0, 5, MAP_CALL(DoSoundStop), "o", NULL },
111  { SIG_SOUNDSCI0, 6, MAP_CALL(DoSoundPause), "i", NULL },
112  { SIG_SOUNDSCI0, 7, MAP_CALL(DoSoundResumeAfterRestore), "", NULL },
113  { SIG_SOUNDSCI0, 8, MAP_CALL(DoSoundMasterVolume), "(i)", NULL },
114  { SIG_SOUNDSCI0, 9, MAP_CALL(DoSoundUpdate), "o", NULL },
115  { SIG_SOUNDSCI0, 10, MAP_CALL(DoSoundFade), "[o0]", kDoSoundFade_workarounds },
116  { SIG_SOUNDSCI0, 11, MAP_CALL(DoSoundGetPolyphony), "", NULL },
117  { SIG_SOUNDSCI0, 12, MAP_CALL(DoSoundStopAll), "", NULL },
118  { SIG_SOUNDSCI1EARLY, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL },
119  { SIG_SOUNDSCI1EARLY, 1, MAP_CALL(DoSoundMute), NULL, NULL },
120  { SIG_SOUNDSCI1EARLY, 2, MAP_EMPTY(DoSoundRestore), NULL, NULL },
121  { SIG_SOUNDSCI1EARLY, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL },
122  { SIG_SOUNDSCI1EARLY, 4, MAP_CALL(DoSoundUpdate), NULL, NULL },
123  { SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL },
124  { SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL },
125  { SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL },
126  { SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL },
127  { SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL },
128  { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds },
129  { SIG_SOUNDSCI1EARLY, 11, MAP_CALL(DoSoundUpdateCues), "o", NULL },
130  { SIG_SOUNDSCI1EARLY, 12, MAP_CALL(DoSoundSendMidi), "oiii", NULL },
131  { SIG_SOUNDSCI1EARLY, 13, MAP_CALL(DoSoundGlobalReverb), "(i)", NULL },
132  { SIG_SOUNDSCI1EARLY, 14, MAP_CALL(DoSoundSetHold), "oi", NULL },
133  { SIG_SOUNDSCI1EARLY, 15, MAP_EMPTY(DoSoundDummy), "", NULL },
134  // ^^ Longbow demo
135  { SIG_SOUNDSCI1LATE, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL },
136  { SIG_SOUNDSCI1LATE, 1, MAP_CALL(DoSoundMute), NULL, NULL },
137  { SIG_SOUNDSCI1LATE, 2, MAP_EMPTY(DoSoundRestore), "", NULL },
138  { SIG_SOUNDSCI1LATE, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL },
139  { SIG_SOUNDSCI1LATE, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL },
140  { SIG_SOUNDSCI1LATE, 5, MAP_CALL(DoSoundSuspend), "i", NULL },
141  { SIG_SOUNDSCI1LATE, 6, MAP_CALL(DoSoundInit), NULL, NULL },
142  { SIG_SOUNDSCI1LATE, 7, MAP_CALL(DoSoundDispose), NULL, NULL },
143  { SIG_SOUNDSCI1LATE, 8, MAP_CALL(DoSoundPlay), NULL, NULL },
144  { SIG_SOUNDSCI1LATE, 9, MAP_CALL(DoSoundStop), NULL, NULL },
145  { SIG_SOUNDSCI1LATE, 10, MAP_CALL(DoSoundPause), NULL, NULL },
146  { SIG_SOUNDSCI1LATE, 11, MAP_CALL(DoSoundFade), "oiiii(i)", kDoSoundFade_workarounds },
147  { SIG_SOUNDSCI1LATE, 12, MAP_CALL(DoSoundSetHold), NULL, NULL },
148  { SIG_SOUNDSCI1LATE, 13, MAP_EMPTY(DoSoundDummy), NULL, NULL },
149  { SIG_SOUNDSCI1LATE, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL },
150  { SIG_SOUNDSCI1LATE, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL },
151  { SIG_SOUNDSCI1LATE, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL },
152  { SIG_SOUNDSCI1LATE, 17, MAP_CALL(DoSoundUpdateCues), NULL, NULL },
153  { SIG_SOUNDSCI1LATE, 18, MAP_CALL(DoSoundSendMidi), "oiii(i)", NULL },
154  { SIG_SOUNDSCI1LATE, 19, MAP_CALL(DoSoundGlobalReverb), NULL, NULL },
155  { SIG_SOUNDSCI1LATE, 20, MAP_CALL(DoSoundUpdate), NULL, NULL },
156 #ifdef ENABLE_SCI32
157  { SIG_SCI32, 0, MAP_CALL(DoSoundMasterVolume), "(i)", NULL },
158  { SIG_SCI32, 1, MAP_CALL(DoSoundMute), "(i)", NULL },
159  { SIG_SCI32, 2, MAP_EMPTY(DoSoundRestore), NULL, NULL },
160  { SIG_SCI32, 3, MAP_CALL(DoSoundGetPolyphony), "", NULL },
161  { SIG_SCI32, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL },
162  { SIG_SCI32, 5, MAP_CALL(DoSoundSuspend), "i", NULL },
163  { SIG_SCI32, 6, MAP_CALL(DoSoundInit), "o", NULL },
164  { SIG_SCI32, 7, MAP_CALL(DoSoundDispose), "o", NULL },
165  { SIG_SCI32, 8, MAP_CALL(DoSoundPlay), "o", kDoSoundPlay_workarounds },
166  { SIG_SCI32, 9, MAP_CALL(DoSoundStop), "o", NULL },
167  { SIG_SCI32, 10, MAP_CALL(DoSoundPause), "[o0]i", NULL },
168  { SIG_SCI32, 11, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds },
169  { SIG_SCI32, 12, MAP_CALL(DoSoundSetHold), "oi", NULL },
170  { SIG_SCI32, 13, MAP_EMPTY(DoSoundDummy), NULL, NULL },
171  { SIG_SCI32, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL },
172  { SIG_SCI32, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL },
173  { SIG_SCI32, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL },
174  { SIG_SCI32, 17, MAP_CALL(DoSoundUpdateCues), "o", NULL },
175  { SIG_SCI32, 18, MAP_CALL(DoSoundSendMidi), "oiiii", NULL },
176  { SIG_SCI32, 19, MAP_CALL(DoSoundGlobalReverb), "(i)", NULL },
177  { SIG_SCI32, 20, MAP_CALL(DoSoundUpdate), "o", NULL },
178 #endif
179  SCI_SUBOPENTRY_TERMINATOR
180 };
181 
182 #ifdef ENABLE_SCI32
183 // NOTE: In SSCI, some 'unused' kDoAudio subops are actually called indirectly
184 // by kDoSound:
185 //
186 // kDoSoundGetAudioCapability -> kDoAudioGetCapability
187 // kDoSoundPlay -> kDoAudioPlay, kDoAudioStop
188 // kDoSoundPause -> kDoAudioPause, kDoAudioResume
189 // kDoSoundFade -> kDoAudioFade
190 // kDoSoundSetVolume -> kDoAudioVolume
191 // kDoSoundSetLoop -> kDoAudioSetLoop
192 // kDoSoundUpdateCues -> kDoAudioPosition
193 //
194 // In ScummVM, logic inside these kernel functions has been moved to methods of
195 // Audio32, and direct calls to Audio32 are made from kDoSound instead.
196 //
197 // Some kDoAudio methods are esoteric and appear to be used only by one or two
198 // games:
199 //
200 // - kDoAudioMixing: Phantasmagoria (other games call this function, but only
201 // to disable the feature)
202 // - kDoAudioHasSignal: SQ6 TalkRandCycle
203 // - kDoAudioPan: Rama RegionSFX::pan method
204 // - kDoAudioCritical: Phantasmagoria, chapter 3, nursery (room 14200), during
205 // the "ghost lullaby" event. It is used to make the
206 // lullaby sound exclusive, but it really doesn't make any
207 // major difference. Returning 0 means "non-critical", i.e.
208 // normal audio behavior.
209 //
210 // Finally, there is a split in SCI2.1mid audio code. QFG4CD & SQ6 do not have
211 // opcodes 18 and 19, but they exist in GK2, KQ7 2.00b, Phantasmagoria 1,
212 // PQ:SWAT, and Torin. It is unknown if they exist in MUMG Deluxe or Shivers 1;
213 // they are not used in either of these games.
214 
215 // version, subId, function-mapping, signature, workarounds
216 static const SciKernelMapSubEntry kDoAudio_subops[] = {
217  { SIG_SCI32, 0, MAP_CALL(DoAudioInit), "", NULL },
218  // SCI2 includes a Sync script that would call
219  // kDoAudioWaitForPlay, but SSCI has no opcode 1 until
220  // SCI2.1early
221  { SIG_SINCE_SCI21, 1, MAP_CALL(DoAudioWaitForPlay), "(i)(i)(i)(i)(i)(i)(i)", NULL },
222  // LSL6 hires Mac passes an extra filename string parameter to play AIFF files
223  { SIG_SCI32, 2, MAP_CALL(DoAudioPlay), "(i)(i)(i)(i)(i)([ir])(i)", NULL },
224  { SIG_SCI32, 3, MAP_CALL(DoAudioStop), "(i)(i)(i)(i)(i)(r)", NULL },
225  { SIG_SCI32, 4, MAP_CALL(DoAudioPause), "(i)(i)(i)(i)(i)(r)", NULL },
226  { SIG_SCI32, 5, MAP_CALL(DoAudioResume), "(i)(i)(i)(i)(i)(r)", kDoAudioResume_workarounds },
227  { SIG_SCI32, 6, MAP_CALL(DoAudioPosition), "(i)(i)(i)(i)(i)(r)", NULL },
228  { SIG_SCI32, 7, MAP_CALL(DoAudioRate), "(i)", NULL },
229  { SIG_SCI32, 8, MAP_CALL(DoAudioVolume), "(i)(i)(i)(i)(i)(i)", NULL },
230  { SIG_SCI32, 9, MAP_CALL(DoAudioGetCapability), "", NULL },
231  { SIG_SCI32, 10, MAP_CALL(DoAudioBitDepth), "(i)", NULL },
232  { SIG_SCI32, 11, MAP_DUMMY(DoAudioDistort), "(i)", NULL },
233  { SIG_SCI32, 12, MAP_CALL(DoAudioMixing), "(i)", NULL },
234  { SIG_SCI2, 13, MAP_EMPTY(DoAudioSetBufferSize), "i", NULL },
235  { SIG_SINCE_SCI21, 13, MAP_CALL(DoAudioChannels), "(i)", NULL },
236  { SIG_SINCE_SCI21, 14, MAP_CALL(DoAudioPreload), "(i)", NULL },
237  { SIG_SINCE_SCI21MID, 15, MAP_CALL(DoAudioFade), "(iiii)(i)(i)", NULL },
238  { SIG_SINCE_SCI21MID, 16, MAP_DUMMY(DoAudioFade36), "iiiii(iii)(i)", NULL },
239  { SIG_SINCE_SCI21MID, 17, MAP_CALL(DoAudioHasSignal), "", NULL },
240  { SIG_SINCE_SCI21MID, 18, MAP_EMPTY(DoAudioCritical), "(i)", NULL },
241  { SIG_SINCE_SCI21MID, 19, MAP_CALL(DoAudioSetLoop), "iii(o)", NULL },
242  { SIG_SINCE_SCI21LATE,20, MAP_CALL(DoAudioPan), "ii(i)(iii)", NULL },
243  { SIG_SINCE_SCI21LATE,21, MAP_CALL(DoAudioPanOff), "i(i)(iii)", NULL },
244  SCI_SUBOPENTRY_TERMINATOR
245 };
246 #endif
247 
248 // version, subId, function-mapping, signature, workarounds
249 static const SciKernelMapSubEntry kGraph_subops[] = {
250  // 1 - load bits
251  { SIG_SCIALL, 2, MAP_CALL(GraphGetColorCount), "", NULL },
252  // 3 - set palette via resource
253  { SIG_SCIALL, 4, MAP_CALL(GraphDrawLine), "iiiii(i)(i)", kGraphDrawLine_workarounds },
254  // 5 - nop
255  // 6 - draw pattern
256  { SIG_SCIALL, 7, MAP_CALL(GraphSaveBox), "iiiii", kGraphSaveBox_workarounds },
257  { SIG_SCIALL, 8, MAP_CALL(GraphRestoreBox), "[r0!]", kGraphRestoreBox_workarounds },
258  // ^ this may get called with invalid references, we check them within restoreBits() and sierra sci behaves the same
259  { SIG_SCIALL, 9, MAP_CALL(GraphFillBoxBackground), "iiii", NULL },
260  { SIG_SCIALL, 10, MAP_CALL(GraphFillBoxForeground), "iiii", kGraphFillBoxForeground_workarounds },
261  { SIG_SCIALL, 11, MAP_CALL(GraphFillBoxAny), "iiiiii(i)(i)", kGraphFillBoxAny_workarounds },
262  { SIG_SCI11, 12, MAP_CALL(GraphUpdateBox), "iiii(i)(r0)", kGraphUpdateBox_workarounds }, // kq6 hires
263  { SIG_SCIALL, 12, MAP_CALL(GraphUpdateBox), "iiii(i)", kGraphUpdateBox_workarounds },
264  { SIG_SCIALL, 13, MAP_CALL(GraphRedrawBox), "iiii", kGraphRedrawBox_workarounds },
265  { SIG_SCIALL, 14, MAP_CALL(GraphAdjustPriority), "ii", NULL },
266  { SIG_SCI11, 15, MAP_CALL(GraphSaveUpscaledHiresBox), "iiii(i)", NULL }, // kq6 hires
267  SCI_SUBOPENTRY_TERMINATOR
268 };
269 
270 // version, subId, function-mapping, signature, workarounds
271 static const SciKernelMapSubEntry kPalVary_subops[] = {
272  { SIG_SCI16, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL },
273  { SIG_SCI16, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL },
274  { SIG_SCI16, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL },
275  { SIG_SCI16, 3, MAP_CALL(PalVaryDeinit), "", NULL },
276  { SIG_SCI16, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL },
277  { SIG_SCI16, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL },
278  { SIG_SCI16, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
279 #ifdef ENABLE_SCI32
280  { SIG_SCI32, 0, MAP_CALL(PalVarySetVary), "i(i)(i)(i)(i)", kPalVarySetVary_workarounds },
281  { SIG_SCI32, 1, MAP_CALL(PalVarySetPercent), "(i)(i)", kPalVarySetPercent_workarounds },
282  { SIG_SCI32, 2, MAP_CALL(PalVaryGetPercent), "", NULL },
283  { SIG_SCI32, 3, MAP_CALL(PalVaryOff), "", NULL },
284  { SIG_SCI32, 4, MAP_CALL(PalVaryMergeTarget), "i", NULL },
285  { SIG_SCI32, 5, MAP_CALL(PalVarySetTime), "i", NULL },
286  { SIG_SCI32, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
287  { SIG_SCI32, 7, MAP_CALL(PalVarySetTarget), "i", NULL },
288  { SIG_SCI32, 8, MAP_CALL(PalVarySetStart), "i", kPalVarySetStart_workarounds },
289  { SIG_SCI32, 9, MAP_CALL(PalVaryMergeStart), "i", kPalVaryMergeStart_workarounds },
290 #endif
291  SCI_SUBOPENTRY_TERMINATOR
292 };
293 
294 // version, subId, function-mapping, signature, workarounds
295 static const SciKernelMapSubEntry kPalette_subops[] = {
296  { SIG_SCI16, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL },
297  { SIG_SCI16, 2, MAP_CALL(PaletteSetFlag), "iii", NULL },
298  { SIG_SCI16, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds },
299  { SIG_SCI16, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL },
300  { SIG_SCI16, 5, MAP_CALL(PaletteFindColor), "iii", NULL },
301  { SIG_SCI16, 6, MAP_CALL(PaletteAnimate), "i*", NULL },
302  { SIG_SCI16, 7, MAP_CALL(PaletteSave), "", NULL },
303  { SIG_SCI16, 8, MAP_CALL(PaletteRestore), "[r0]", NULL },
304 #ifdef ENABLE_SCI32
305  { SIG_SCI32, 1, MAP_CALL(PaletteSetFromResource32), "i(i)", NULL },
306  { SIG_SCI32, 2, MAP_CALL(PaletteSetFade), "iii", NULL },
307  { SIG_SCI32, 3, MAP_CALL(PaletteFindColor32), "iii", NULL },
308  { SIG_SCI32, 4, MAP_CALL(PaletteSetGamma), "i", NULL },
309 #endif
310  SCI_SUBOPENTRY_TERMINATOR
311 };
312 
313 // version, subId, function-mapping, signature, workarounds
314 static const SciKernelMapSubEntry kFileIO_subops[] = {
315  { SIG_SCIALL, 0, MAP_CALL(FileIOOpen), "ri", kFileIOOpen_workarounds },
316  { SIG_SCIALL, 1, MAP_CALL(FileIOClose), "i", NULL },
317  { SIG_SCIALL, 2, MAP_CALL(FileIOReadRaw), "iri", NULL },
318  { SIG_SCIALL, 3, MAP_CALL(FileIOWriteRaw), "iri", NULL },
319  { SIG_SCIALL, 4, MAP_CALL(FileIOUnlink), "r", NULL },
320  { SIG_SCIALL, 5, MAP_CALL(FileIOReadString), "rii", kFileIOReadString_workarounds },
321  { SIG_SCIALL, 6, MAP_CALL(FileIOWriteString), "ir", NULL },
322  { SIG_SCIALL, 7, MAP_CALL(FileIOSeek), "iii", NULL },
323  { SIG_SCIALL, 8, MAP_CALL(FileIOFindFirst), "rri", NULL },
324  { SIG_SCIALL, 9, MAP_CALL(FileIOFindNext), "r", NULL },
325  { SIG_SCIALL, 10, MAP_CALL(FileIOExists), "r", NULL },
326  { SIG_SINCE_SCI11, 11, MAP_CALL(FileIORename), "rr", NULL },
327  { SIG_SINCE_SCI11, 12, MAP_CALL(FileIOCopy), "rr", NULL },
328 #ifdef ENABLE_SCI32
329  { SIG_SINCE_SCI21MID, 13, MAP_CALL(FileIOReadByte), "i", NULL },
330  { SIG_SINCE_SCI21MID, 14, MAP_CALL(FileIOWriteByte), "ii", NULL },
331  { SIG_SINCE_SCI21MID, 15, MAP_CALL(FileIOReadWord), "i", NULL },
332  { SIG_SCI21MID, 16, MAP_CALL(FileIOWriteWord), "ii", NULL },
333  { SIG_SINCE_SCI21LATE,16, MAP_CALL(FileIOWriteWord), "i[.!]", NULL },
334  { SIG_SINCE_SCI21MID, 17, "FileIOCheckFreeSpace", kCheckFreeSpace, "i(r)", kFileIOCheckFreeSpace_workarounds },
335  { SIG_SINCE_SCI21MID, 18, MAP_CALL(FileIOGetCWD), "r", NULL },
336  { SIG_SINCE_SCI21MID, 19, MAP_CALL(FileIOIsValidDirectory), "[ro]", NULL },
337 #endif
338  SCI_SUBOPENTRY_TERMINATOR
339 };
340 
341 #ifdef ENABLE_SCI32
342 
343 // version, subId, function-mapping, signature, workarounds
344 static const SciKernelMapSubEntry kPalCycle_subops[] = {
345  { SIG_SCI32, 0, MAP_CALL(PalCycleSetCycle), "iii(i)", NULL },
346  { SIG_SCI32, 1, MAP_CALL(PalCycleDoCycle), "i(i)", NULL },
347  { SIG_SCI32, 2, MAP_CALL(PalCyclePause), "(i)", NULL },
348  { SIG_SCI32, 3, MAP_CALL(PalCycleOn), "(i)", NULL },
349  { SIG_SCI32, 4, MAP_CALL(PalCycleOff), "(i)", NULL },
350  SCI_SUBOPENTRY_TERMINATOR
351 };
352 
353 // version, subId, function-mapping, signature, workarounds
354 static const SciKernelMapSubEntry kSave_subops[] = {
355  { SIG_SCI32, 0, MAP_CALL(SaveGame32), "[r0]i[r0][r0]", NULL },
356  { SIG_SCI32, 1, MAP_CALL(RestoreGame32), "[r0]i[r0]", NULL },
357  // System script 64994 in several SCI2.1mid games (KQ7 2.00b, Phant1,
358  // PQ:SWAT, SQ6, Torin) calls GetSaveDir with an extra unused argument, and
359  // it is easier to just handle it here than to bother with creating
360  // workarounds
361  { SIG_SCI32, 2, MAP_CALL(GetSaveDir), "(r)", NULL },
362  { SIG_SCI32, 3, MAP_CALL(CheckSaveGame32), "ri[r0]", NULL },
363  // Subop 4 hasn't been encountered yet
364  { SIG_SCI32, 5, MAP_CALL(GetSaveFiles32), "rrr", NULL },
365  { SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL },
366  { SIG_SCI32, 7, MAP_CALL(MakeSaveFileName), "rri", NULL },
367  { SIG_SCI32, 8, MAP_EMPTY(GameIsRestarting), "(.*)", NULL },
368  SCI_SUBOPENTRY_TERMINATOR
369 };
370 
371 // version, subId, function-mapping, signature, workarounds
372 static const SciKernelMapSubEntry kFont_subops[] = {
373  { SIG_SINCE_SCI21MID, 0, MAP_CALL(PointSize), "i", NULL },
374  { SIG_SINCE_SCI21MID, 1, MAP_CALL(SetFontRes), "ii", NULL },
375  SCI_SUBOPENTRY_TERMINATOR
376 };
377 
378 // version, subId, function-mapping, signature, workarounds
379 static const SciKernelMapSubEntry kText_subops[] = {
380  { SIG_SINCE_SCI21MID, 0, MAP_CALL(TextSize32), "r[r0]i(i)(i)", NULL },
381  { SIG_SINCE_SCI21MID, 1, MAP_CALL(TextWidth), "ri", NULL },
382  SCI_SUBOPENTRY_TERMINATOR
383 };
384 
385 // version, subId, function-mapping, signature, workarounds
386 static const SciKernelMapSubEntry kBitmap_subops[] = {
387  { SIG_SINCE_SCI21, 0, MAP_CALL(BitmapCreate), "iiii(i)(i)(i)", NULL },
388  { SIG_SINCE_SCI21, 1, MAP_CALL(BitmapDestroy), "[r!]", NULL },
389  { SIG_SINCE_SCI21, 2, MAP_DUMMY(BitmapDrawLine), "riiiii(i)(i)", NULL },
390  { SIG_SINCE_SCI21, 3, MAP_CALL(BitmapDrawView), "riii(i)(i)(0)(i)(i)", NULL },
391  { SIG_SINCE_SCI21, 4, MAP_CALL(BitmapDrawText), "rriiiiiiiiiii", NULL },
392  { SIG_SINCE_SCI21, 5, MAP_CALL(BitmapDrawColor), "riiiii", NULL },
393  { SIG_SINCE_SCI21, 6, MAP_DUMMY(BitmapDrawBitmap), "rr(i)(i)(i)", NULL },
394  { SIG_SINCE_SCI21, 7, MAP_DUMMY(BitmapInvert), "riiiiii", NULL },
395  { SIG_SINCE_SCI21MID, 8, MAP_CALL(BitmapSetOrigin), "rii", NULL },
396  { SIG_SINCE_SCI21MID, 9, MAP_CALL(BitmapCreateFromView), "iii(i)(i)(i)([r0])", NULL },
397  { SIG_SINCE_SCI21MID, 10, MAP_DUMMY(BitmapCopyPixels), "rr", NULL },
398  { SIG_SINCE_SCI21MID, 11, MAP_DUMMY(BitmapClone), "r", NULL },
399  { SIG_SINCE_SCI21MID, 12, MAP_CALL(BitmapGetInfo), "r(i)(i)", NULL },
400  { SIG_SINCE_SCI21LATE,13, MAP_DUMMY(BitmapScale), "r...ii", NULL },
401  { SIG_SINCE_SCI21LATE,14, MAP_DUMMY(BitmapCreateFromUnknown), "......", NULL },
402  { SIG_SCI3, 15, MAP_DUMMY(Bitmap), "(.*)", NULL },
403  { SIG_SCI3, 16, MAP_DUMMY(Bitmap), "(.*)", NULL },
404  SCI_SUBOPENTRY_TERMINATOR
405 };
406 
407 // version, subId, function-mapping, signature, workarounds
408 static const SciKernelMapSubEntry kCD_subops[] = {
409  { SIG_SINCE_SCI21MID, 0, MAP_CALL(CheckCD), "(i)(i)", NULL },
410  { SIG_SINCE_SCI21MID, 1, MAP_CALL(GetSavedCD), "", NULL },
411  SCI_SUBOPENTRY_TERMINATOR
412 };
413 
414 // version, subId, function-mapping, signature, workarounds
415 static const SciKernelMapSubEntry kList_subops[] = {
416  { SIG_SINCE_SCI21, 0, MAP_CALL(NewList), "", NULL },
417  { SIG_SINCE_SCI21, 1, MAP_CALL(DisposeList), "l", NULL },
418  { SIG_SINCE_SCI21, 2, MAP_CALL(NewNode), ".(.)", NULL },
419  { SIG_SINCE_SCI21, 3, MAP_CALL(FirstNode), "[l0]", NULL },
420  { SIG_SINCE_SCI21, 4, MAP_CALL(LastNode), "l", NULL },
421  { SIG_SINCE_SCI21, 5, MAP_CALL(EmptyList), "l", NULL },
422  { SIG_SINCE_SCI21, 6, MAP_CALL(NextNode), "n", NULL },
423  { SIG_SINCE_SCI21, 7, MAP_CALL(PrevNode), "n", NULL },
424  { SIG_SINCE_SCI21, 8, MAP_CALL(NodeValue), "[n0]", NULL },
425  { SIG_SINCE_SCI21, 9, MAP_CALL(AddAfter), "lnn(.)", NULL },
426  { SIG_SINCE_SCI21, 10, MAP_CALL(AddToFront), "ln(.)", NULL },
427  { SIG_SINCE_SCI21, 11, MAP_CALL(AddToEnd), "ln(.)", NULL },
428  { SIG_SINCE_SCI21, 12, MAP_CALL(AddBefore), "ln.", NULL },
429  { SIG_SINCE_SCI21, 13, MAP_CALL(MoveToFront), "ln", NULL },
430  { SIG_SINCE_SCI21, 14, MAP_CALL(MoveToEnd), "ln", NULL },
431  { SIG_SINCE_SCI21, 15, MAP_CALL(FindKey), "l.", NULL },
432  { SIG_SINCE_SCI21, 16, MAP_CALL(DeleteKey), "l.", NULL },
433  { SIG_SINCE_SCI21, 17, MAP_CALL(ListAt), "li", kListAt_workarounds },
434  { SIG_SINCE_SCI21, 18, MAP_CALL(ListIndexOf) , "l[io]", NULL },
435  { SIG_SINCE_SCI21, 19, MAP_CALL(ListEachElementDo), "li(.*)", NULL },
436  { SIG_SINCE_SCI21, 20, MAP_CALL(ListFirstTrue), "li(.*)", NULL },
437  { SIG_SINCE_SCI21, 21, MAP_CALL(ListAllTrue), "li(.*)", NULL },
438  { SIG_SINCE_SCI21, 22, MAP_CALL(ListSort), "li(i)", NULL },
439  SCI_SUBOPENTRY_TERMINATOR
440 };
441 
442 // version, subId, function-mapping, signature, workarounds
443 static const SciKernelMapSubEntry kShowMovieWin_subops[] = {
444  { SIG_SCI2, 0, MAP_CALL(ShowMovieWinOpen), "r", NULL },
445  { SIG_SCI2, 1, MAP_CALL(ShowMovieWinInit), "ii(ii)", NULL },
446  { SIG_SCI2, 2, MAP_CALL(ShowMovieWinPlay), "i", NULL },
447  { SIG_SCI2, 6, MAP_CALL(ShowMovieWinClose), "", NULL },
448  { SIG_SINCE_SCI21, 0, MAP_CALL(ShowMovieWinOpen), "ir", NULL },
449  { SIG_SINCE_SCI21, 1, MAP_CALL(ShowMovieWinInit), "iii(ii)", NULL },
450  { SIG_SINCE_SCI21, 2, MAP_CALL(ShowMovieWinPlay), "i(ii)(i)(i)", NULL },
451  { SIG_SINCE_SCI21, 6, MAP_CALL(ShowMovieWinClose), "i", NULL },
452  // Since movies are rendered within the graphics engine in ScummVM,
453  // it is not necessary to copy the palette from SCI to MCI, so this
454  // can be a no-op
455  { SIG_SINCE_SCI21, 7, MAP_EMPTY(ShowMovieWinSetPalette), "i", NULL },
456  { SIG_SINCE_SCI21, 8, MAP_CALL(ShowMovieWinGetDuration), "i", NULL },
457  { SIG_SINCE_SCI21, 11, MAP_CALL(ShowMovieWinCue), "ii", NULL },
458  { SIG_SINCE_SCI21, 14, MAP_CALL(ShowMovieWinPlayUntilEvent), "i(i)", NULL },
459  { SIG_SINCE_SCI21, 15, MAP_CALL(ShowMovieWinInitDouble), "iii", NULL },
460  SCI_SUBOPENTRY_TERMINATOR
461 };
462 
463 // There are a lot of subops to PlayVMD, but only a few of them are ever
464 // actually used by games
465 // version, subId, function-mapping, signature, workarounds
466 static const SciKernelMapSubEntry kPlayVMD_subops[] = {
467  { SIG_SINCE_SCI21, 0, MAP_CALL(PlayVMDOpen), "r(i)(i)", NULL },
468  { SIG_SINCE_SCI21, 1, MAP_CALL(PlayVMDInit), "ii(i)(i)(ii)", NULL },
469  { SIG_SINCE_SCI21, 6, MAP_CALL(PlayVMDClose), "", NULL },
470  { SIG_SINCE_SCI21, 7, MAP_CALL(PlayVMDIgnorePalettes), "", NULL },
471  { SIG_SINCE_SCI21, 10, MAP_CALL(PlayVMDGetStatus), "", NULL },
472  { SIG_SINCE_SCI21, 14, MAP_CALL(PlayVMDPlayUntilEvent), "i(i)(i)", NULL },
473  { SIG_SINCE_SCI21, 16, MAP_CALL(PlayVMDShowCursor), "i", NULL },
474  { SIG_SINCE_SCI21, 17, MAP_CALL(PlayVMDStartBlob), "", NULL },
475  { SIG_SINCE_SCI21, 18, MAP_CALL(PlayVMDStopBlobs), "", NULL },
476  { SIG_SINCE_SCI21, 19, MAP_CALL(PlayVMDAddBlob), "iiiii", NULL },
477  { SIG_SINCE_SCI21, 20, MAP_CALL(PlayVMDDeleteBlob), "i", NULL },
478  { SIG_SINCE_SCI21, 21, MAP_CALL(PlayVMDSetBlackoutArea), "iiii", NULL },
479  { SIG_SINCE_SCI21, 23, MAP_CALL(PlayVMDRestrictPalette), "ii", NULL },
480  { SIG_SINCE_SCI21LATE,27, MAP_CALL(PlayVMDSetPlane), "i(i)", NULL },
481  { SIG_SINCE_SCI21LATE,28, MAP_EMPTY(PlayVMDSetPreload), "i", NULL },
482  { SIG_SINCE_SCI21LATE,31, MAP_EMPTY(PlayVMDSetFrameRate), "i", NULL },
483  SCI_SUBOPENTRY_TERMINATOR
484 };
485 
486 // version, subId, function-mapping, signature, workarounds
487 static const SciKernelMapSubEntry kRobot_subops[] = {
488  { SIG_SINCE_SCI21, 0, MAP_CALL(RobotOpen), "ioiii(i)", NULL },
489  { SIG_SINCE_SCI21, 1, MAP_CALL(RobotShowFrame), "i(ii)", NULL },
490  { SIG_SINCE_SCI21, 2, MAP_CALL(RobotGetFrameSize), "r", NULL },
491  { SIG_SINCE_SCI21, 4, MAP_CALL(RobotPlay), "", NULL },
492  { SIG_SINCE_SCI21, 5, MAP_CALL(RobotGetIsFinished), "", NULL },
493  { SIG_SINCE_SCI21, 6, MAP_CALL(RobotGetIsInitialized), "", NULL },
494  { SIG_SINCE_SCI21, 7, MAP_CALL(RobotClose), "", NULL },
495  { SIG_SINCE_SCI21, 8, MAP_CALL(RobotGetCue), "o", NULL },
496  { SIG_SINCE_SCI21, 10, MAP_CALL(RobotPause), "", NULL },
497  { SIG_SINCE_SCI21, 11, MAP_CALL(RobotGetFrameNo), "", NULL },
498  { SIG_SINCE_SCI21, 12, MAP_CALL(RobotSetPriority), "i", NULL },
499  SCI_SUBOPENTRY_TERMINATOR
500 };
501 
502 // version, subId, function-mapping, signature, workarounds
503 static const SciKernelMapSubEntry kPlayDuck_subops[] = {
504  { SIG_SCI3, 1, MAP_CALL(PlayDuckPlay), "iiiii", NULL },
505  { SIG_SCI3, 2, MAP_CALL(PlayDuckSetFrameOut), "i", NULL },
506  { SIG_SCI3, 5, MAP_CALL(PlayDuckClose), "", NULL },
507  { SIG_SCI3, 6, MAP_CALL(PlayDuckSetVolume), "i", NULL },
508  SCI_SUBOPENTRY_TERMINATOR
509 };
510 
511 // version, subId, function-mapping, signature, workarounds
512 static const SciKernelMapSubEntry kRemapColors_subops[] = {
513  { SIG_SCI32, 0, MAP_CALL(RemapColorsOff), "(i)", NULL },
514  { SIG_SCI32, 1, MAP_CALL(RemapColorsByRange), "iiii(i)", NULL },
515  { SIG_SCI32, 2, MAP_CALL(RemapColorsByPercent), "ii(i)", NULL },
516  { SIG_SCI32, 3, MAP_CALL(RemapColorsToGray), "ii(i)", NULL },
517  { SIG_SCI32, 4, MAP_CALL(RemapColorsToPercentGray), "iii(i)", NULL },
518  { SIG_SCI32, 5, MAP_CALL(RemapColorsBlockRange), "ii", NULL },
519  SCI_SUBOPENTRY_TERMINATOR
520 };
521 
522 // version, subId, function-mapping, signature, workarounds
523 static const SciKernelMapSubEntry kArray_subops[] = {
524  { SIG_SCI32, 0, MAP_CALL(ArrayNew), "ii", NULL },
525  { SIG_SCI32, 1, MAP_CALL(ArrayGetSize), "r", NULL },
526  { SIG_SCI32, 2, MAP_CALL(ArrayGetElement), "ri", NULL },
527  { SIG_SCI32, 3, MAP_CALL(ArraySetElements), "ri(.*)", kArraySetElements_workarounds },
528  { SIG_SCI32, 4, MAP_CALL(ArrayFree), "[r0]", NULL },
529  { SIG_SCI32, 5, MAP_CALL(ArrayFill), "riii", kArrayFill_workarounds },
530  { SIG_SCI32, 6, MAP_CALL(ArrayCopy), "ri[r0]ii", NULL },
531  // there is no subop 7
532  { SIG_SCI32, 8, MAP_CALL(ArrayDuplicate), "r", NULL },
533  { SIG_SCI32, 9, MAP_CALL(ArrayGetData), "[or0]", NULL },
534  { SIG_SCI3, 10, MAP_CALL(ArrayByteCopy), "ririi", NULL },
535  SCI_SUBOPENTRY_TERMINATOR
536 };
537 
538 // version, subId, function-mapping, signature, workarounds
539 static const SciKernelMapSubEntry kString_subops[] = {
540  // every single copy of script 64918 in SCI2 through 2.1mid calls StringNew
541  // with a second type argument which is unused (new strings are always type
542  // 3)
543  { SIG_THRU_SCI21MID, 0, MAP_CALL(StringNew), "i(i)", NULL },
544  { SIG_THRU_SCI21MID, 1, MAP_CALL(ArrayGetSize), "r", NULL },
545  { SIG_THRU_SCI21MID, 2, MAP_CALL(StringGetChar), "[r0]i", NULL },
546  { SIG_THRU_SCI21MID, 3, MAP_CALL(ArraySetElements), "ri(i*)", kArraySetElements_workarounds },
547  { SIG_THRU_SCI21MID, 4, MAP_CALL(StringFree), "[r0]", NULL },
548  { SIG_THRU_SCI21MID, 5, MAP_CALL(ArrayFill), "riii", kArrayFill_workarounds },
549  { SIG_THRU_SCI21MID, 6, MAP_CALL(ArrayCopy), "ri[r0]ii", NULL },
550  { SIG_SCI32, 7, MAP_CALL(StringCompare), "[r0][r0](i)", NULL },
551 
552  { SIG_THRU_SCI21MID, 8, MAP_CALL(ArrayDuplicate), "r", NULL },
553  { SIG_THRU_SCI21MID, 9, MAP_CALL(ArrayGetData), "[or0]", NULL },
554  { SIG_THRU_SCI21MID, 10, MAP_CALL(StringLength), "[r0]", NULL },
555  { SIG_THRU_SCI21MID, 11, MAP_CALL(StringFormat), "[or0](.*)", NULL },
556  { SIG_THRU_SCI21MID, 12, MAP_CALL(StringFormatAt), "r[or0](.*)", NULL },
557  { SIG_THRU_SCI21MID, 13, MAP_CALL(StringToInteger), "[r0]", NULL },
558  { SIG_THRU_SCI21MID, 14, MAP_CALL(StringTrim), "[r0]i(i)", NULL },
559  { SIG_THRU_SCI21MID, 15, MAP_CALL(StringToUpperCase), "[r0]", NULL },
560  { SIG_THRU_SCI21MID, 16, MAP_CALL(StringToLowerCase), "[r0]", NULL },
561  { SIG_THRU_SCI21MID, 17, MAP_CALL(StringReplaceSubstring), "[r0][r0][r0][r0]", NULL },
562  { SIG_THRU_SCI21MID, 18, MAP_CALL(StringReplaceSubstringEx), "[r0][r0][r0][r0]", NULL },
563 
564  { SIG_SINCE_SCI21LATE, 8, MAP_CALL(StringLength), "[r0]", NULL },
565  { SIG_SINCE_SCI21LATE, 9, MAP_CALL(StringFormat), "[or0](.*)", NULL },
566  { SIG_SINCE_SCI21LATE,10, MAP_CALL(StringFormatAt), "[r0][or0](.*)", NULL },
567  { SIG_SINCE_SCI21LATE,11, MAP_CALL(StringToInteger), "[r0]", NULL },
568  { SIG_SINCE_SCI21LATE,12, MAP_CALL(StringTrim), "[r0]i(i)", NULL },
569  { SIG_SINCE_SCI21LATE,13, MAP_CALL(StringToUpperCase), "[r0]", NULL },
570  { SIG_SINCE_SCI21LATE,14, MAP_CALL(StringToLowerCase), "[r0]", NULL },
571  { SIG_SINCE_SCI21LATE,15, MAP_CALL(StringReplaceSubstring), "[r0][r0][r0][r0]", NULL },
572  { SIG_SINCE_SCI21LATE,16, MAP_CALL(StringReplaceSubstringEx), "[r0][r0][r0][r0]", NULL },
573  SCI_SUBOPENTRY_TERMINATOR
574 };
575 
576 // version, subId, function-mapping, signature, workarounds
577 static const SciKernelMapSubEntry kCelInfo_subops[] = {
578  { SIG_SINCE_SCI21MID, 0, MAP_CALL(CelInfoGetOriginX), "iii", NULL },
579  { SIG_SINCE_SCI21MID, 1, MAP_CALL(CelInfoGetOriginY), "iii", NULL },
580  { SIG_SINCE_SCI21MID, 2, MAP_EMPTY(CelInfo), "iii", NULL },
581  { SIG_SINCE_SCI21MID, 3, MAP_EMPTY(CelInfo), "iii", NULL },
582  { SIG_SINCE_SCI21MID, 4, MAP_CALL(CelInfoGetPixel), "iiiii", NULL },
583  SCI_SUBOPENTRY_TERMINATOR
584 };
585 
586 // version, subId, function-mapping, signature, workarounds
587 static const SciKernelMapSubEntry kCelLink_subops[] = {
588  { SIG_SINCE_SCI21MID, 0, MAP_DUMMY(CelLink0), "", NULL },
589  { SIG_SINCE_SCI21MID, 1, MAP_DUMMY(CelLink1), "", NULL },
590  { SIG_SINCE_SCI21MID, 2, MAP_CALL(CelLinkGetX), "iiii", NULL },
591  { SIG_SINCE_SCI21MID, 3, MAP_CALL(CelLinkGetY), "iiii", NULL },
592  { SIG_SINCE_SCI21MID, 4, MAP_DUMMY(CelLink4), "", NULL },
593  SCI_SUBOPENTRY_TERMINATOR
594 };
595 
596 // version, subId, function-mapping, signature, workarounds
597 static const SciKernelMapSubEntry kScrollWindow_subops[] = {
598  { SIG_SCI32, 0, MAP_CALL(ScrollWindowCreate), "oi", NULL },
599  { SIG_SCI32, 1, MAP_CALL(ScrollWindowAdd), "iriii(i)", kScrollWindowAdd_workarounds },
600  { SIG_SCI32, 2, MAP_DUMMY(ScrollWindowClear), "i", NULL },
601  { SIG_SCI32, 3, MAP_CALL(ScrollWindowPageUp), "i", NULL },
602  { SIG_SCI32, 4, MAP_CALL(ScrollWindowPageDown), "i", NULL },
603  { SIG_SCI32, 5, MAP_CALL(ScrollWindowUpArrow), "i", NULL },
604  { SIG_SCI32, 6, MAP_CALL(ScrollWindowDownArrow), "i", NULL },
605  { SIG_SCI32, 7, MAP_CALL(ScrollWindowHome), "i", NULL },
606  { SIG_SCI32, 8, MAP_CALL(ScrollWindowEnd), "i", NULL },
607  { SIG_SCI32, 9, MAP_DUMMY(ScrollWindowResize), "i.", NULL },
608  { SIG_SCI32, 10, MAP_CALL(ScrollWindowWhere), "ii", NULL },
609  { SIG_SCI32, 11, MAP_CALL(ScrollWindowGo), "i..", NULL },
610  { SIG_SCI32, 12, MAP_DUMMY(ScrollWindowInsert), "i.....", NULL },
611  { SIG_SCI32, 13, MAP_DUMMY(ScrollWindowDelete), "i.", NULL },
612  { SIG_SCI32, 14, MAP_CALL(ScrollWindowModify), "iiriii(i)", NULL },
613  { SIG_SCI32, 15, MAP_CALL(ScrollWindowHide), "i", NULL },
614  { SIG_SCI32, 16, MAP_CALL(ScrollWindowShow), "i", NULL },
615  { SIG_SCI32, 17, MAP_CALL(ScrollWindowDestroy), "i", NULL },
616  // LSL6hires uses kScrollWindowText and kScrollWindowReconstruct to try to save
617  // and restore the content of the game's subtitle window, but this feature did not
618  // use the normal save/load functionality of the engine and was actually broken
619  // (all text formatting was missing on restore). Since there is no real reason to
620  // save the subtitle scrollback anyway, we just ignore calls to these two functions.
621  { SIG_SCI32, 18, MAP_EMPTY(ScrollWindowText), "i", NULL },
622  { SIG_SCI32, 19, MAP_EMPTY(ScrollWindowReconstruct), "i.", NULL },
623  SCI_SUBOPENTRY_TERMINATOR
624 };
625 
626 #endif
627 
629  const char *name;
630  KernelFunctionCall *function;
631 
632  SciVersion fromVersion;
633  SciVersion toVersion;
634  byte forPlatform;
635 
636  const char *signature;
637  const SciKernelMapSubEntry *subFunctions;
638  const SciWorkaroundEntry *workarounds;
639 };
640 
641 // name, version/platform, signature, sub-signatures, workarounds
642 static SciKernelMapEntry s_kernelMap[] = {
643  { MAP_CALL(Abs), SIG_EVERYWHERE, "i", NULL, kAbs_workarounds },
644  { MAP_CALL(AddAfter), SIG_EVERYWHERE, "lnn", NULL, NULL },
645  { MAP_CALL(AddMenu), SIG_EVERYWHERE, "rr", NULL, NULL },
646  { MAP_CALL(AddToEnd), SIG_EVERYWHERE, "ln", NULL, NULL },
647  { MAP_CALL(AddToFront), SIG_EVERYWHERE, "ln", NULL, NULL },
648  { MAP_CALL(AddToPic), SIG_EVERYWHERE, "[il](iiiiii)", NULL, NULL },
649  { MAP_CALL(Animate), SIG_EVERYWHERE, "(l0)(i)", NULL, kAnimate_workarounds },
650  { MAP_CALL(AssertPalette), SIG_EVERYWHERE, "i", NULL, NULL },
651  { MAP_CALL(AvoidPath), SIG_EVERYWHERE, "ii(.*)", NULL, NULL },
652  { MAP_CALL(BaseSetter), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL },
653 #ifdef ENABLE_SCI32
654  { "BaseSetter", kBaseSetter32, SIG_SCI32, SIGFOR_ALL, "o", NULL, NULL },
655 #endif
656  { MAP_CALL(CanBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL },
657  { MAP_CALL(CantBeHere), SIG_SCI16, SIGFOR_ALL, "o(l)", NULL, NULL },
658 #ifdef ENABLE_SCI32
659  { MAP_CALL(CantBeHere), SIG_SCI32, SIGFOR_ALL, "ol", NULL, NULL },
660 #endif
661  { MAP_CALL(CelHigh), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelHigh_workarounds },
662  { MAP_CALL(CelWide), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelWide_workarounds },
663 #ifdef ENABLE_SCI32
664  { "CelHigh", kCelHigh32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, NULL },
665  { "CelWide", kCelWide32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, kCelWide_workarounds },
666 #endif
667  { MAP_CALL(CheckFreeSpace), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "r(i)", NULL, NULL },
668  { MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL },
669  { MAP_CALL(CheckFreeSpace), SIG_SCI16, SIGFOR_ALL, "r", NULL, NULL },
670 #ifdef ENABLE_SCI32
671  { "CheckSaveGame", kCheckSaveGame32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
672 #endif
673  { MAP_CALL(CheckSaveGame), SIG_SCI16, SIGFOR_ALL, ".*", NULL, NULL },
674  { MAP_CALL(Clone), SIG_EVERYWHERE, "o", NULL, NULL },
675  { MAP_CALL(CoordPri), SIG_EVERYWHERE, "i(i)", NULL, NULL },
676  { MAP_CALL(CosDiv), SIG_EVERYWHERE, "ii", NULL, NULL },
677  { MAP_CALL(DeleteKey), SIG_EVERYWHERE, "l.", NULL, kDeleteKey_workarounds },
678  { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, kDeviceInfo_workarounds }, // subop
679  { MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, kDisplay_workarounds },
680  // ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro
681  // restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same
682  { MAP_CALL(DirLoop), SIG_EVERYWHERE, "oi", NULL, kDirLoop_workarounds },
683  { MAP_CALL(DisposeClone), SIG_EVERYWHERE, "o", NULL, NULL },
684  { MAP_CALL(DisposeList), SIG_EVERYWHERE, "l", NULL, NULL },
685  { MAP_CALL(DisposeScript), SIG_EVERYWHERE, "i(i*)", NULL, kDisposeScript_workarounds },
686  { MAP_CALL(DisposeWindow), SIG_EVERYWHERE, "i(i)", NULL, NULL },
687  { MAP_CALL(DoAudio), SIG_SCI16, SIGFOR_ALL, "i(.*)", NULL, NULL }, // subop
688 #ifdef ENABLE_SCI32
689  { "DoAudio", kDoAudio32, SIG_SCI32, SIGFOR_ALL, "(.*)", kDoAudio_subops, NULL },
690 #endif
691  { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o(i)", NULL, NULL },
692  { MAP_CALL(DoBresen), SIG_EVERYWHERE, "o", NULL, NULL },
693  { MAP_CALL(DoSound), SIG_EVERYWHERE, "i(.*)", kDoSound_subops, NULL },
694  { MAP_CALL(DoSync), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
695  { MAP_CALL(DrawCel), SIG_SCI11, SIGFOR_PC, "iiiii(i)(i)([ri])", NULL, NULL }, // reference for kq6 hires
696  { MAP_CALL(DrawCel), SIG_EVERYWHERE, "iiiii(i)(i)", NULL, NULL },
697  { MAP_CALL(DrawControl), SIG_EVERYWHERE, "o", NULL, NULL },
698  { MAP_CALL(DrawMenuBar), SIG_EVERYWHERE, "i", NULL, NULL },
699  { MAP_CALL(DrawPic), SIG_EVERYWHERE, "i(i)(i)(i)", NULL, NULL },
700  { MAP_CALL(DrawStatus), SIG_EVERYWHERE, "[r0](i)(i)", NULL, NULL },
701  { MAP_CALL(EditControl), SIG_EVERYWHERE, "[o0][o0]", NULL, NULL },
702  { MAP_CALL(Empty), SIG_EVERYWHERE, "(.*)", NULL, NULL },
703  { MAP_CALL(EmptyList), SIG_EVERYWHERE, "l", NULL, NULL },
704  { "FClose", kFileIOClose, SIG_EVERYWHERE, "i", NULL, NULL },
705  { "FGets", kFileIOReadString, SIG_EVERYWHERE, "rii", NULL, kFileIOReadString_workarounds },
706  { "FOpen", kFileIOOpen, SIG_EVERYWHERE, "ri", NULL, NULL },
707  { "FPuts", kFileIOWriteString, SIG_EVERYWHERE, "ir", NULL, NULL },
708  { MAP_CALL(FileIO), SIG_EVERYWHERE, "i([.!]*)", kFileIO_subops, NULL },
709  { MAP_CALL(FindKey), SIG_EVERYWHERE, "l.", NULL, kFindKey_workarounds },
710  { MAP_CALL(FirstNode), SIG_EVERYWHERE, "[l0]", NULL, NULL },
711  { MAP_CALL(FlushResources), SIG_EVERYWHERE, "i", NULL, NULL },
712  { MAP_CALL(Format), SIG_EVERYWHERE, "r[ri](.*)", NULL, NULL },
713  { MAP_CALL(GameIsRestarting), SIG_EVERYWHERE, "(i)", NULL, NULL },
714  { MAP_CALL(GetAngle), SIG_EVERYWHERE, "iiii", NULL, kGetAngle_workarounds },
715  { MAP_CALL(GetCWD), SIG_EVERYWHERE, "r", NULL, kGetCWD_workarounds },
716  { MAP_CALL(GetDistance), SIG_EVERYWHERE, "ii(i)(i)(i)(i)", NULL, NULL },
717  { MAP_CALL(GetEvent), SIG_SCIALL, SIGFOR_MAC, "io(i*)", NULL, NULL },
718  { MAP_CALL(GetEvent), SIG_EVERYWHERE, "io", NULL, NULL },
719  { MAP_CALL(GetFarText), SIG_EVERYWHERE, "ii[r0]", NULL, NULL },
720  { MAP_CALL(GetMenu), SIG_EVERYWHERE, "i.", NULL, NULL },
721  { MAP_CALL(GetMessage), SIG_EVERYWHERE, "iiir", NULL, NULL },
722  { MAP_CALL(GetPort), SIG_EVERYWHERE, "", NULL, NULL },
723 #ifdef ENABLE_SCI32
724  { MAP_CALL(GetSaveDir), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "(r)", NULL, NULL },
725 #endif
726  { MAP_CALL(GetSaveDir), SIG_SCI16, SIGFOR_ALL, "", NULL, NULL },
727 #ifdef ENABLE_SCI32
728  { "GetSaveFiles", kGetSaveFiles32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "rrr", NULL, NULL },
729 #endif
730  { MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, kGetSaveFiles_workarounds },
731  { MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL },
732  { MAP_CALL(GlobalToLocal), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL },
733 #ifdef ENABLE_SCI32
734  { "GlobalToLocal", kGlobalToLocal32, SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL },
735 #endif
736  { MAP_CALL(Graph), SIG_SCI16, SIGFOR_ALL, NULL, kGraph_subops, NULL },
737 #ifdef ENABLE_SCI32
738  { MAP_EMPTY(Graph), SIG_SCI32, SIGFOR_ALL, "(.*)", NULL, NULL },
739 #endif
740  { MAP_CALL(HaveMouse), SIG_EVERYWHERE, "", NULL, NULL },
741  { MAP_CALL(HiliteControl), SIG_EVERYWHERE, "o", NULL, NULL },
742  { MAP_CALL(InitBresen), SIG_EVERYWHERE, "o(i)", NULL, NULL },
743  { MAP_CALL(Intersections), SIG_EVERYWHERE, "iiiiriiiri", NULL, NULL },
744  { MAP_CALL(IsItSkip), SIG_EVERYWHERE, "iiiii", NULL, NULL },
745  { MAP_CALL(IsObject), SIG_EVERYWHERE, ".", NULL, kIsObject_workarounds },
746  { MAP_CALL(Joystick), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
747  { MAP_CALL(LastNode), SIG_EVERYWHERE, "l", NULL, NULL },
748  { MAP_CALL(Load), SIG_EVERYWHERE, "ii(i*)", NULL, NULL },
749  { MAP_CALL(LocalToGlobal), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL },
750 #ifdef ENABLE_SCI32
751  { "LocalToGlobal", kLocalToGlobal32, SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL },
752 #endif
753  { MAP_CALL(Lock), SIG_EVERYWHERE, "ii(i)", NULL, kLock_workarounds },
754  { MAP_CALL(MapKeyToDir), SIG_EVERYWHERE, "o", NULL, NULL },
755  { MAP_CALL(Memory), SIG_EVERYWHERE, "i(.*)", NULL, kMemory_workarounds }, // subop
756  { MAP_CALL(MemoryInfo), SIG_EVERYWHERE, "i", NULL, NULL },
757  { MAP_CALL(MemorySegment), SIG_EVERYWHERE, "ir(i)", NULL, NULL }, // subop
758  { MAP_CALL(MenuSelect), SIG_EVERYWHERE, "o(i)", NULL, NULL },
759  { MAP_CALL(MergePoly), SIG_EVERYWHERE, "rli", NULL, NULL },
760  { MAP_CALL(Message), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
761  { MAP_CALL(MoveCursor), SIG_EVERYWHERE, "ii", NULL, kMoveCursor_workarounds },
762  { MAP_CALL(NewList), SIG_EVERYWHERE, "", NULL, NULL },
763  { MAP_CALL(NewNode), SIG_EVERYWHERE, "..", NULL, NULL },
764  { MAP_CALL(NewWindow), SIG_SCIALL, SIGFOR_MAC, ".*", NULL, NULL },
765  { MAP_CALL(NewWindow), SIG_SCI0, SIGFOR_ALL, "iiii[r0]i(i)(i)(i)", NULL, NULL },
766  { MAP_CALL(NewWindow), SIG_SCI1, SIGFOR_ALL, "iiii[ir]i(i)(i)([ir])(i)(i)(i)(i)", NULL, NULL },
767  { MAP_CALL(NewWindow), SIG_SCI11, SIGFOR_ALL, "iiiiiiii[r0]i(i)(i)(i)", NULL, kNewWindow_workarounds },
768  { MAP_CALL(NextNode), SIG_EVERYWHERE, "n", NULL, NULL },
769  { MAP_CALL(NodeValue), SIG_EVERYWHERE, "[n0]", NULL, NULL },
770  { MAP_CALL(NumCels), SIG_EVERYWHERE, "o", NULL, NULL },
771  { MAP_CALL(NumLoops), SIG_EVERYWHERE, "o", NULL, NULL },
772  { MAP_CALL(OnControl), SIG_EVERYWHERE, "ii(i)(i)(i)", NULL, NULL },
773  { MAP_CALL(PalVary), SIG_EVERYWHERE, "i(i*)", kPalVary_subops, NULL },
774  { MAP_CALL(Palette), SIG_EVERYWHERE, "i(.*)", kPalette_subops, NULL },
775  { MAP_CALL(Parse), SIG_EVERYWHERE, "ro", NULL, NULL },
776  { MAP_CALL(PicNotValid), SIG_EVERYWHERE, "(i)", NULL, NULL },
777  { MAP_CALL(Platform), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL },
778 #ifdef ENABLE_SCI32
779  { "Platform", kPlatform32, SIG_SCI32, SIGFOR_MAC, "(.*)", NULL, NULL },
780  { "Platform", kPlatform32, SIG_SCI32, SIGFOR_ALL, "(i)", NULL, kPlatform32_workarounds },
781 #endif
782  { MAP_CALL(Portrait), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop
783  { MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL },
784  { MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL },
785  { MAP_CALL(Random), SIG_EVERYWHERE, "(i)(i)", NULL, kRandom_workarounds },
786  { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, kReadNumber_workarounds },
787  { MAP_CALL(RemapColors), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, NULL },
788  { MAP_CALL(RemapColorsKawa), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", NULL, NULL },
789 #ifdef ENABLE_SCI32
790  { "RemapColors", kRemapColors32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", kRemapColors_subops, NULL },
791 #endif
792  { MAP_CALL(ResCheck), SIG_EVERYWHERE, "ii(iiii)", NULL, NULL },
793  { MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL },
794  { "RestartGame", kRestartGame16, SIG_SCI16, SIGFOR_ALL, "", NULL, NULL },
795 #ifdef ENABLE_SCI32
796  { MAP_EMPTY(RestartGame), SIG_SCI32, SIGFOR_ALL, "", NULL, NULL },
797  { "RestoreGame", kRestoreGame32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
798 #endif
799  { MAP_CALL(RestoreGame), SIG_EVERYWHERE, "[r0]i[r0]", NULL, NULL },
800  { MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL },
801 #ifdef ENABLE_SCI32
802  { "SaveGame", kSaveGame32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri[r0][r0]", NULL, NULL },
803  { MAP_CALL(ScummVMSaveLoad), SIG_SCI32, SIGFOR_ALL, "([iro])([iro])", NULL, NULL },
804 #endif
805  { MAP_CALL(SaveGame), SIG_SCI16, SIGFOR_ALL, "[r0]i[r0](r0)", NULL, NULL },
806  { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL },
807  { MAP_CALL(SetCursor), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(iiiiii)", NULL, NULL },
808  { MAP_CALL(SetCursor), SIG_SCI16, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, kSetCursor_workarounds },
809 #ifdef ENABLE_SCI32
810  { "SetCursor", kSetCursor32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)", NULL, kSetCursor_workarounds },
811 #endif
812  { MAP_CALL(SetDebug), SIG_EVERYWHERE, "(i*)", NULL, NULL },
813  { MAP_CALL(SetJump), SIG_EVERYWHERE, "oiii", NULL, NULL },
814  { MAP_CALL(SetMenu), SIG_EVERYWHERE, "i(.*)", NULL, NULL },
815  { MAP_CALL(SetNowSeen), SIG_SCI16, SIGFOR_ALL, "o(i)", NULL, NULL },
816 #ifdef ENABLE_SCI32
817  { "SetNowSeen", kSetNowSeen32, SIG_SCI32, SIGFOR_ALL, "o", NULL, NULL },
818 #endif
819  { MAP_CALL(SetPort), SIG_EVERYWHERE, "i(iiiii)(i)", NULL, kSetPort_workarounds },
820  { MAP_CALL(SetQuitStr), SIG_EVERYWHERE, "r", NULL, NULL },
821  { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL },
822  { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL },
823  { MAP_CALL(ShakeScreen), SIG_SCI16, SIGFOR_ALL, "(i)(i)", NULL, NULL },
824 #ifdef ENABLE_SCI32
825  { "ShakeScreen", kShakeScreen32, SIG_SCI32, SIGFOR_ALL, "i(i)", NULL, NULL },
826 #endif
827  { MAP_CALL(ShowMovie), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL },
828 #ifdef ENABLE_SCI32
829  { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_DOS, "ri(i)(i)", NULL, NULL },
830  { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_MAC, "ri(i)(i)", NULL, NULL },
831  { "ShowMovie", kShowMovieWin, SIG_SCI32, SIGFOR_WIN, "(.*)", kShowMovieWin_subops, NULL },
832 #endif
833  { MAP_CALL(Show), SIG_EVERYWHERE, "i", NULL, NULL },
834  { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL },
835  { MAP_CALL(ScummVMSleep), SIG_EVERYWHERE, "i", NULL, NULL },
836  { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL },
837  { MAP_CALL(Sqrt), SIG_EVERYWHERE, "i", NULL, NULL },
838  { MAP_CALL(StrAt), SIG_EVERYWHERE, "ri(i)", NULL, kStrAt_workarounds },
839  { MAP_CALL(StrCat), SIG_EVERYWHERE, "rr", NULL, NULL },
840  { MAP_CALL(StrCmp), SIG_EVERYWHERE, "rr(i)", NULL, NULL },
841  { MAP_CALL(StrCpy), SIG_EVERYWHERE, "r[r0](i)", NULL, kStrCpy_workarounds },
842  { MAP_CALL(StrEnd), SIG_EVERYWHERE, "r", NULL, NULL },
843  { MAP_CALL(StrLen), SIG_EVERYWHERE, "[r0]", NULL, kStrLen_workarounds },
844  { MAP_CALL(StrSplit), SIG_EVERYWHERE, "rr[r0]", NULL, NULL },
845  { MAP_CALL(TextColors), SIG_SCI16, SIGFOR_ALL, "(i*)", NULL, NULL },
846  { MAP_CALL(TextFonts), SIG_SCI16, SIGFOR_ALL, "(i*)", NULL, NULL },
847  { MAP_CALL(TextSize), SIG_SCI16, SIGFOR_MAC, "r[r0]i(i)(r0)(i)", NULL, NULL },
848  { MAP_CALL(TextSize), SIG_SCI16, SIGFOR_ALL, "r[r0]i(i)(r0)", NULL, NULL },
849  { MAP_CALL(TimesCos), SIG_EVERYWHERE, "ii", NULL, NULL },
850  { "CosMult", kTimesCos, SIG_EVERYWHERE, "ii", NULL, NULL },
851  { MAP_CALL(TimesCot), SIG_EVERYWHERE, "ii", NULL, NULL },
852  { MAP_CALL(TimesSin), SIG_EVERYWHERE, "ii", NULL, NULL },
853  { "SinMult", kTimesSin, SIG_EVERYWHERE, "ii", NULL, NULL },
854  { MAP_CALL(TimesTan), SIG_EVERYWHERE, "ii", NULL, NULL },
855  { MAP_CALL(UnLoad), SIG_EVERYWHERE, "i[ir!]", NULL, kUnLoad_workarounds },
856  // ^ We allow invalid references here (e.g. bug #6600), since they will be invalidated anyway by the call itself
857  { MAP_CALL(ValidPath), SIG_EVERYWHERE, "r", NULL, NULL },
858  { MAP_CALL(Wait), SIG_SCI16, SIGFOR_ALL, "i", NULL, kWait_workarounds },
859 
860  // Unimplemented SCI0-SCI1.1 unused functions, always mapped to kDummy
861  { MAP_DUMMY(InspectObj), SIG_EVERYWHERE, "(.*)", NULL, NULL },
862  { MAP_DUMMY(ShowSends), SIG_EVERYWHERE, "(.*)", NULL, NULL },
863  { MAP_DUMMY(ShowObjs), SIG_EVERYWHERE, "(.*)", NULL, NULL },
864  { MAP_DUMMY(ShowFree), SIG_EVERYWHERE, "(.*)", NULL, NULL },
865  { MAP_DUMMY(StackUsage), SIG_EVERYWHERE, "(.*)", NULL, NULL },
866  { MAP_DUMMY(Profiler), SIG_EVERYWHERE, "(.*)", NULL, NULL },
867  { MAP_DUMMY(ShiftScreen), SIG_EVERYWHERE, "(.*)", NULL, NULL },
868  { MAP_DUMMY(ListOps), SIG_EVERYWHERE, "(.*)", NULL, NULL },
869  // Used by the sysLogger class (e.g. script 952 in GK1CD), a class used to report bugs by Sierra's testers
870  { MAP_DUMMY(ATan), SIG_EVERYWHERE, "(.*)", NULL, NULL },
871  { MAP_DUMMY(Record), SIG_EVERYWHERE, "(.*)", NULL, NULL },
872  { MAP_DUMMY(PlayBack), SIG_EVERYWHERE, "(.*)", NULL, NULL },
873  { MAP_DUMMY(DbugStr), SIG_EVERYWHERE, "(.*)", NULL, NULL },
874  // Used in Kawa's SCI11+
875  { MAP_CALL(KawaDbugStr), SIG_SCI11, SIGFOR_ALL, "(.*)", NULL, NULL },
876  { MAP_CALL(KawaHacks), SIG_SCI11, SIGFOR_ALL, "(.*)", NULL, NULL },
877 
878  // =======================================================================================================
879 
880 #ifdef ENABLE_SCI32
881  // SCI2 Kernel Functions
882  // TODO: whoever knows his way through those calls, fix the signatures.
883  { "TextSize", kTextSize32, SIG_THRU_SCI21EARLY, SIGFOR_ALL, "r[r0]i(i)", NULL, NULL },
884  { MAP_DUMMY(TextColors), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL },
885  { MAP_DUMMY(TextFonts), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL },
886 
887  { MAP_CALL(AddPlane), SIG_EVERYWHERE, "o", NULL, NULL },
888  { MAP_CALL(AddScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
889  { MAP_CALL(Array), SIG_EVERYWHERE, "i(.*)", kArray_subops, NULL },
890  { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL },
891  { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL },
892  { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
893  { "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "[r!]", NULL, NULL },
894  { MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, kFrameOut_workarounds },
895  { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL },
896  { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL },
897  { MAP_CALL(IsHiRes), SIG_EVERYWHERE, "", NULL, NULL },
898  { MAP_CALL(ListAllTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL },
899  { MAP_CALL(ListAt), SIG_EVERYWHERE, "li", NULL, NULL },
900  { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE, "li(.*)", NULL, NULL },
901  { MAP_CALL(ListFirstTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL },
902  { MAP_CALL(ListIndexOf), SIG_EVERYWHERE, "l[o0]", NULL, NULL },
903  // kMessageBox is used only by KQ7 1.51
904  { MAP_CALL(MessageBox), SIG_SCI32, SIGFOR_ALL, "rri", NULL, NULL },
905  { "OnMe", kIsOnMe, SIG_EVERYWHERE, "iioi", NULL, NULL },
906  // Purge is used by the memory manager in SSCI to ensure that X number of bytes (the so called "unmovable
907  // memory") are available when the current room changes. This is similar to the SCI0-SCI1.1 FlushResources
908  // call, with the added functionality of ensuring that a specific amount of memory is available. We have
909  // our own memory manager and garbage collector, thus we simply call FlushResources, which in turn invokes
910  // our garbage collector (i.e. the SCI0-SCI1.1 semantics).
911  { "Purge", kFlushResources, SIG_EVERYWHERE, "i", NULL, NULL },
912  { MAP_CALL(SetShowStyle), SIG_THRU_SCI21MID, SIGFOR_ALL, "ioiiiii([ri])(i)", NULL, NULL },
913  { MAP_CALL(SetShowStyle), SIG_SCI21LATE, SIGFOR_PC, "ioiiiii([ri])([ri])(i)", NULL, NULL },
914  { MAP_CALL(SetShowStyle), SIG_SINCE_SCI21LATE, SIGFOR_ALL, "ioiiiiii(r)(i)", NULL, NULL },
915  { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", kString_subops, NULL },
916  { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL },
917  { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
918  { MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL },
919  { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
920  { MAP_CALL(MakeSaveCatName), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "rr", NULL, NULL },
921  { MAP_CALL(MakeSaveFileName), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "rri", NULL, NULL },
922  { MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiii(i)(i)", NULL, NULL },
923  { MAP_CALL(PalCycle), SIG_EVERYWHERE, "(.*)", kPalCycle_subops, NULL },
924 
925  // SCI2 Empty functions
926 
927  // Debug function used to track resources
928  { MAP_EMPTY(ResourceTrack), SIG_EVERYWHERE, "(.*)", NULL, NULL },
929  // Future TODO: This call is used in the floppy version of QFG4 to add
930  // vibration to exotic mice with force feedback, such as the Logitech
931  // Cyberman and Wingman mice. Since this is only used for very exotic
932  // hardware and we have no direct and cross-platform way of communicating
933  // with them via SDL, plus we would probably need to make changes to common
934  // code, this call is mapped to an empty function for now as it's a rare
935  // feature not worth the effort.
936  { MAP_EMPTY(VibrateMouse), SIG_EVERYWHERE, "(.*)", NULL, NULL },
937 
938  // Unused / debug SCI2 unused functions, always mapped to kDummy
939 
940  // AddMagnify/DeleteMagnify are both called by script 64979 (the Magnifier
941  // object) in GK1 only. There is also an associated empty magnifier view
942  // (view 1), however, it doesn't seem to be used anywhere, as all the
943  // magnifier closeups (e.g. in scene 470) are normal views. Thus, these
944  // are marked as dummy, so if they're ever used the engine will error out.
945  { MAP_DUMMY(AddMagnify), SIG_EVERYWHERE, "(.*)", NULL, NULL },
946  { MAP_DUMMY(DeleteMagnify), SIG_EVERYWHERE, "(.*)", NULL, NULL },
947  { MAP_DUMMY(RepaintPlane), SIG_EVERYWHERE, "o", NULL, NULL },
948  { MAP_DUMMY(InspectObject), SIG_EVERYWHERE, "(.*)", NULL, NULL },
949  // Profiler (same as SCI0-SCI1.1)
950  // Record (same as SCI0-SCI1.1)
951  // PlayBack (same as SCI0-SCI1.1)
952  { MAP_DUMMY(MonoOut), SIG_EVERYWHERE, "(.*)", NULL, NULL },
953  { MAP_DUMMY(SetFatalStr), SIG_EVERYWHERE, "(.*)", NULL, NULL },
954  { MAP_DUMMY(IntegrityChecking),SIG_EVERYWHERE, "(.*)", NULL, NULL },
955  { MAP_DUMMY(CheckIntegrity), SIG_EVERYWHERE, "(.*)", NULL, NULL },
956  { MAP_DUMMY(MarkMemory), SIG_EVERYWHERE, "(.*)", NULL, NULL },
957  { MAP_DUMMY(GetHighItemPri), SIG_EVERYWHERE, "(.*)", NULL, NULL },
958  { MAP_DUMMY(ShowStylePercent), SIG_EVERYWHERE, "(.*)", NULL, NULL },
959  { MAP_DUMMY(InvertRect), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL },
960  { MAP_CALL(InputText), SIG_EVERYWHERE, "rri", NULL, NULL },
961  { MAP_CALL(TextWidth), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "ri", NULL, NULL },
962  { MAP_CALL(PointSize), SIG_THRU_SCI21EARLY, SIGFOR_ALL, "i", NULL, NULL },
963 
964  // SCI2.1 Kernel Functions
965  { "CheckCDisc", kCheckCD, SIG_SCI21EARLY, SIGFOR_ALL, "(i)", NULL, NULL },
966  { "GetSaveCDisc", kGetSavedCD, SIG_SCI21EARLY, SIGFOR_ALL, "", NULL, NULL },
967  { MAP_CALL(CD), SIG_SINCE_SCI21MID, SIGFOR_ALL, "(.*)", kCD_subops, NULL },
968  { MAP_CALL(IsOnMe), SIG_EVERYWHERE, "iioi", NULL, NULL },
969  { MAP_CALL(List), SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL },
970  { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL },
971  { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", kPlayVMD_subops, NULL },
972  { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", kRobot_subops, NULL },
973  { MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL },
974  { MAP_CALL(Text), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kText_subops, NULL },
975  { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii(i)(i)", NULL, NULL },
976  { MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL },
977  { MAP_CALL(WinHelp), SIG_EVERYWHERE, "(.*)", NULL, NULL },
978  { MAP_CALL(GetConfig), SIG_EVERYWHERE, "ro", NULL, NULL },
979  { MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL },
980  { MAP_CALL(CelInfo), SIG_SINCE_SCI21MID, SIGFOR_ALL, "(.*)", kCelInfo_subops, NULL },
981  { MAP_CALL(SetLanguage), SIG_SINCE_SCI21MID, SIGFOR_ALL, "r", NULL, NULL },
982  { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "i(.*)", kScrollWindow_subops, NULL },
983  { MAP_CALL(SetFontRes), SIG_SCI21EARLY, SIGFOR_ALL, "ii", NULL, NULL },
984  { MAP_CALL(Font), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kFont_subops, NULL },
985  { MAP_CALL(Bitmap), SIG_EVERYWHERE, "i([.!]*)", kBitmap_subops, NULL },
986  { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiii(iiiii)", NULL, NULL },
987  // The first argument is a ScreenItem instance ID that is created by the
988  // engine, not the VM; as a result, in ScummVM, this argument looks like
989  // an integer and not an object, although it is an object reference.
990  { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "ioiiii(iiiii)", NULL, NULL },
991  { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "io", NULL, NULL },
992 
993  // SCI2.1 Empty Functions
994 
995  // Debug function, used in of Shivers (demo and full). It's marked as a
996  // stub in the original interpreters, but it gets called by the game scripts.
997  // Usually, it gets called with a string (which is the output format) and a
998  // variable number of parameters
999  { MAP_CALL(PrintDebug), SIG_SCI32, SIGFOR_ALL, "r(.*)", NULL, NULL },
1000 
1001  // SetWindowsOption is used to set Windows specific options, like for example the title bar visibility of
1002  // the game window in Phantasmagoria 2. We ignore these settings completely.
1003  { MAP_EMPTY(SetWindowsOption), SIG_EVERYWHERE, "ii", NULL, NULL },
1004 
1005  // Debug function called whenever the current room changes
1006  { MAP_EMPTY(NewRoom), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1007 
1008  // Unused / debug SCI2.1 unused functions, always mapped to kDummy
1009 
1010  // The debug functions are called from the inbuilt debugger or polygon
1011  // editor in SCI2.1 games. Related objects are: PEditor, EditablePolygon,
1012  // aeDisplayClass and scalerCode
1013  { MAP_DUMMY(FindSelector), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1014  { MAP_DUMMY(FindClass), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1015  { MAP_DUMMY(CelRect), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1016  { MAP_DUMMY(BaseLineSpan), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1017  { MAP_CALL(CelLink), SIG_SINCE_SCI21MID, SIGFOR_ALL, "(.*)", kCelLink_subops, NULL },
1018  { MAP_DUMMY(AddPolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1019  { MAP_DUMMY(DeletePolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1020  { MAP_DUMMY(UpdatePolygon), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1021  { MAP_DUMMY(Table), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1022  { MAP_DUMMY(LoadChunk), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1023  { MAP_DUMMY(Priority), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1024  { MAP_CALL(WinDLL), SIG_SINCE_SCI21MID, SIGFOR_ALL, "ir(r)", NULL, NULL },
1025  { MAP_DUMMY(DeletePic), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1026  { MAP_DUMMY(GetSierraProfileString), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1027 
1028  // Unused / debug functions in the in-between SCI2.1 interpreters
1029  { MAP_DUMMY(PreloadResource), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1030  { MAP_DUMMY(TestPoly), SIG_EVERYWHERE, "(.*)", NULL, NULL },
1031 
1032  // Used by Phantasmagoria 1, script 64981 (used in the chase scene)
1033  { MAP_CALL(SetHotRectangles), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(r)", NULL, NULL },
1034 
1035  // Used by SQ6 to scroll through the inventory via the up/down buttons
1036  { MAP_CALL(MovePlaneItems), SIG_SINCE_SCI21, SIGFOR_ALL, "oii(i)", NULL, NULL },
1037 
1038  { MAP_CALL(SetPalStyleRange), SIG_EVERYWHERE, "ii", NULL, NULL },
1039 
1040  { MAP_CALL(MorphOn), SIG_EVERYWHERE, "", NULL, NULL },
1041 
1042  // SCI3 Kernel Functions
1043  { MAP_EMPTY(Minimize), SIG_SCI3, SIGFOR_ALL, "(.*)", NULL, NULL },
1044  { MAP_CALL(PlayDuck), SIG_SCI3, SIGFOR_ALL, "(.*)", kPlayDuck_subops,NULL },
1045  { MAP_CALL(WebConnect), SIG_SCI3, SIGFOR_ALL, "(r)", NULL, NULL },
1046  { MAP_CALL(WinExec), SIG_SCI3, SIGFOR_ALL, "r", NULL, NULL },
1047 #endif
1048 
1049  { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL }
1050 };
1051 
1053 static const char *const s_defaultKernelNames[] = {
1054  /*0x00*/ "Load",
1055  /*0x01*/ "UnLoad",
1056  /*0x02*/ "ScriptID",
1057  /*0x03*/ "DisposeScript",
1058  /*0x04*/ "Clone",
1059  /*0x05*/ "DisposeClone",
1060  /*0x06*/ "IsObject",
1061  /*0x07*/ "RespondsTo",
1062  /*0x08*/ "DrawPic",
1063  /*0x09*/ "Show",
1064  /*0x0a*/ "PicNotValid",
1065  /*0x0b*/ "Animate",
1066  /*0x0c*/ "SetNowSeen",
1067  /*0x0d*/ "NumLoops",
1068  /*0x0e*/ "NumCels",
1069  /*0x0f*/ "CelWide",
1070  /*0x10*/ "CelHigh",
1071  /*0x11*/ "DrawCel",
1072  /*0x12*/ "AddToPic",
1073  /*0x13*/ "NewWindow",
1074  /*0x14*/ "GetPort",
1075  /*0x15*/ "SetPort",
1076  /*0x16*/ "DisposeWindow",
1077  /*0x17*/ "DrawControl",
1078  /*0x18*/ "HiliteControl",
1079  /*0x19*/ "EditControl",
1080  /*0x1a*/ "TextSize",
1081  /*0x1b*/ "Display",
1082  /*0x1c*/ "GetEvent",
1083  /*0x1d*/ "GlobalToLocal",
1084  /*0x1e*/ "LocalToGlobal",
1085  /*0x1f*/ "MapKeyToDir",
1086  /*0x20*/ "DrawMenuBar",
1087  /*0x21*/ "MenuSelect",
1088  /*0x22*/ "AddMenu",
1089  /*0x23*/ "DrawStatus",
1090  /*0x24*/ "Parse",
1091  /*0x25*/ "Said",
1092  /*0x26*/ "SetSynonyms", // Portrait (KQ6 hires)
1093  /*0x27*/ "HaveMouse",
1094  /*0x28*/ "SetCursor",
1095  // FOpen (SCI0)
1096  // FPuts (SCI0)
1097  // FGets (SCI0)
1098  // FClose (SCI0)
1099  /*0x29*/ "SaveGame",
1100  /*0x2a*/ "RestoreGame",
1101  /*0x2b*/ "RestartGame",
1102  /*0x2c*/ "GameIsRestarting",
1103  /*0x2d*/ "DoSound",
1104  /*0x2e*/ "NewList",
1105  /*0x2f*/ "DisposeList",
1106  /*0x30*/ "NewNode",
1107  /*0x31*/ "FirstNode",
1108  /*0x32*/ "LastNode",
1109  /*0x33*/ "EmptyList",
1110  /*0x34*/ "NextNode",
1111  /*0x35*/ "PrevNode",
1112  /*0x36*/ "NodeValue",
1113  /*0x37*/ "AddAfter",
1114  /*0x38*/ "AddToFront",
1115  /*0x39*/ "AddToEnd",
1116  /*0x3a*/ "FindKey",
1117  /*0x3b*/ "DeleteKey",
1118  /*0x3c*/ "Random",
1119  /*0x3d*/ "Abs",
1120  /*0x3e*/ "Sqrt",
1121  /*0x3f*/ "GetAngle",
1122  /*0x40*/ "GetDistance",
1123  /*0x41*/ "Wait",
1124  /*0x42*/ "GetTime",
1125  /*0x43*/ "StrEnd",
1126  /*0x44*/ "StrCat",
1127  /*0x45*/ "StrCmp",
1128  /*0x46*/ "StrLen",
1129  /*0x47*/ "StrCpy",
1130  /*0x48*/ "Format",
1131  /*0x49*/ "GetFarText",
1132  /*0x4a*/ "ReadNumber",
1133  /*0x4b*/ "BaseSetter",
1134  /*0x4c*/ "DirLoop",
1135  /*0x4d*/ "CanBeHere", // CantBeHere in newer SCI versions
1136  /*0x4e*/ "OnControl",
1137  /*0x4f*/ "InitBresen",
1138  /*0x50*/ "DoBresen",
1139  /*0x51*/ "Platform", // DoAvoider (SCI0)
1140  /*0x52*/ "SetJump",
1141  /*0x53*/ "SetDebug", // for debugging
1142  /*0x54*/ "InspectObj", // for debugging
1143  /*0x55*/ "ShowSends", // for debugging
1144  /*0x56*/ "ShowObjs", // for debugging
1145  /*0x57*/ "ShowFree", // for debugging
1146  /*0x58*/ "MemoryInfo",
1147  /*0x59*/ "StackUsage", // for debugging
1148  /*0x5a*/ "Profiler", // for debugging
1149  /*0x5b*/ "GetMenu",
1150  /*0x5c*/ "SetMenu",
1151  /*0x5d*/ "GetSaveFiles",
1152  /*0x5e*/ "GetCWD",
1153  /*0x5f*/ "CheckFreeSpace",
1154  /*0x60*/ "ValidPath",
1155  /*0x61*/ "CoordPri",
1156  /*0x62*/ "StrAt",
1157  /*0x63*/ "DeviceInfo",
1158  /*0x64*/ "GetSaveDir",
1159  /*0x65*/ "CheckSaveGame",
1160  /*0x66*/ "ShakeScreen",
1161  /*0x67*/ "FlushResources",
1162  /*0x68*/ "SinMult",
1163  /*0x69*/ "CosMult",
1164  /*0x6a*/ "SinDiv",
1165  /*0x6b*/ "CosDiv",
1166  /*0x6c*/ "Graph",
1167  /*0x6d*/ "Joystick",
1168  // End of kernel function table for SCI0
1169  /*0x6e*/ "ShiftScreen", // never called?
1170  /*0x6f*/ "Palette",
1171  /*0x70*/ "MemorySegment",
1172  /*0x71*/ "Intersections", // MoveCursor (SCI1 late), PalVary (SCI1.1)
1173  /*0x72*/ "Memory",
1174  /*0x73*/ "ListOps", // never called?
1175  /*0x74*/ "FileIO",
1176  /*0x75*/ "DoAudio",
1177  /*0x76*/ "DoSync",
1178  /*0x77*/ "AvoidPath",
1179  /*0x78*/ "Sort", // StrSplit (SCI01)
1180  /*0x79*/ "ATan", // never called?
1181  /*0x7a*/ "Lock",
1182  /*0x7b*/ "StrSplit",
1183  /*0x7c*/ "GetMessage", // Message (SCI1.1)
1184  /*0x7d*/ "IsItSkip",
1185  /*0x7e*/ "MergePoly",
1186  /*0x7f*/ "ResCheck",
1187  /*0x80*/ "AssertPalette",
1188  /*0x81*/ "TextColors",
1189  /*0x82*/ "TextFonts",
1190  /*0x83*/ "Record", // for debugging
1191  /*0x84*/ "PlayBack", // for debugging
1192  /*0x85*/ "ShowMovie",
1193  /*0x86*/ "SetVideoMode",
1194  /*0x87*/ "SetQuitStr",
1195  /*0x88*/ "DbugStr", // for debugging
1196  /*0x89*/ "Empty",
1197  /*0x8a*/ "Empty"
1198 };
1199 
1200 #ifdef ENABLE_SCI32
1201 
1202 // NOTE: 0x72-0x79, 0x85-0x86, 0x88 are from the GK2 demo (which has debug support) and are
1203 // just Dummy in other SCI2 games.
1204 static const char *const sci2_default_knames[] = {
1205  /*0x00*/ "Load",
1206  /*0x01*/ "UnLoad",
1207  /*0x02*/ "ScriptID",
1208  /*0x03*/ "DisposeScript",
1209  /*0x04*/ "Lock",
1210  /*0x05*/ "ResCheck",
1211  /*0x06*/ "Purge",
1212  /*0x07*/ "Clone",
1213  /*0x08*/ "DisposeClone",
1214  /*0x09*/ "RespondsTo",
1215  /*0x0a*/ "SetNowSeen",
1216  /*0x0b*/ "NumLoops",
1217  /*0x0c*/ "NumCels",
1218  /*0x0d*/ "CelWide",
1219  /*0x0e*/ "CelHigh",
1220  /*0x0f*/ "GetHighPlanePri",
1221  /*0x10*/ "GetHighItemPri", // unused function
1222  /*0x11*/ "ShakeScreen",
1223  /*0x12*/ "OnMe",
1224  /*0x13*/ "ShowMovie",
1225  /*0x14*/ "SetVideoMode",
1226  /*0x15*/ "AddScreenItem",
1227  /*0x16*/ "DeleteScreenItem",
1228  /*0x17*/ "UpdateScreenItem",
1229  /*0x18*/ "FrameOut",
1230  /*0x19*/ "AddPlane",
1231  /*0x1a*/ "DeletePlane",
1232  /*0x1b*/ "UpdatePlane",
1233  /*0x1c*/ "RepaintPlane", // unused function
1234  /*0x1d*/ "SetShowStyle",
1235  /*0x1e*/ "ShowStylePercent", // unused function
1236  /*0x1f*/ "SetScroll",
1237  /*0x20*/ "AddMagnify",
1238  /*0x21*/ "DeleteMagnify",
1239  /*0x22*/ "IsHiRes",
1240  /*0x23*/ "Graph", // Robot in early SCI2.1 games with a SCI2 kernel table
1241  /*0x24*/ "InvertRect", // only in SCI2, not used in any SCI2 game
1242  /*0x25*/ "TextSize",
1243  /*0x26*/ "Message",
1244  /*0x27*/ "TextColors",
1245  /*0x28*/ "TextFonts",
1246  /*0x29*/ "Dummy",
1247  /*0x2a*/ "SetQuitStr",
1248  /*0x2b*/ "EditText",
1249  /*0x2c*/ "InputText",
1250  /*0x2d*/ "CreateTextBitmap",
1251  /*0x2e*/ "DisposeTextBitmap", // Priority in early SCI2.1 games with a SCI2 kernel table
1252  /*0x2f*/ "GetEvent",
1253  /*0x30*/ "GlobalToLocal",
1254  /*0x31*/ "LocalToGlobal",
1255  /*0x32*/ "MapKeyToDir",
1256  /*0x33*/ "HaveMouse",
1257  /*0x34*/ "SetCursor",
1258  /*0x35*/ "VibrateMouse",
1259  /*0x36*/ "SaveGame",
1260  /*0x37*/ "RestoreGame",
1261  /*0x38*/ "RestartGame",
1262  /*0x39*/ "GameIsRestarting",
1263  /*0x3a*/ "MakeSaveCatName",
1264  /*0x3b*/ "MakeSaveFileName",
1265  /*0x3c*/ "GetSaveFiles",
1266  /*0x3d*/ "GetSaveDir",
1267  /*0x3e*/ "CheckSaveGame",
1268  /*0x3f*/ "CheckFreeSpace",
1269  /*0x40*/ "DoSound",
1270  /*0x41*/ "DoAudio",
1271  /*0x42*/ "DoSync",
1272  /*0x43*/ "NewList",
1273  /*0x44*/ "DisposeList",
1274  /*0x45*/ "NewNode",
1275  /*0x46*/ "FirstNode",
1276  /*0x47*/ "LastNode",
1277  /*0x48*/ "EmptyList",
1278  /*0x49*/ "NextNode",
1279  /*0x4a*/ "PrevNode",
1280  /*0x4b*/ "NodeValue",
1281  /*0x4c*/ "AddAfter",
1282  /*0x4d*/ "AddToFront",
1283  /*0x4e*/ "AddToEnd",
1284  /*0x4f*/ "Dummy",
1285  /*0x50*/ "Dummy",
1286  /*0x51*/ "FindKey",
1287  /*0x52*/ "Dummy",
1288  /*0x53*/ "Dummy",
1289  /*0x54*/ "Dummy",
1290  /*0x55*/ "DeleteKey",
1291  /*0x56*/ "Dummy",
1292  /*0x57*/ "Dummy",
1293  /*0x58*/ "ListAt",
1294  /*0x59*/ "ListIndexOf",
1295  /*0x5a*/ "ListEachElementDo",
1296  /*0x5b*/ "ListFirstTrue",
1297  /*0x5c*/ "ListAllTrue",
1298  /*0x5d*/ "Random",
1299  /*0x5e*/ "Abs",
1300  /*0x5f*/ "Sqrt",
1301  /*0x60*/ "GetAngle",
1302  /*0x61*/ "GetDistance",
1303  /*0x62*/ "ATan",
1304  /*0x63*/ "SinMult",
1305  /*0x64*/ "CosMult",
1306  /*0x65*/ "SinDiv",
1307  /*0x66*/ "CosDiv",
1308  /*0x67*/ "GetTime",
1309  /*0x68*/ "Platform",
1310  /*0x69*/ "BaseSetter",
1311  /*0x6a*/ "DirLoop",
1312  /*0x6b*/ "CantBeHere",
1313  /*0x6c*/ "InitBresen",
1314  /*0x6d*/ "DoBresen",
1315  /*0x6e*/ "SetJump",
1316  /*0x6f*/ "AvoidPath",
1317  /*0x70*/ "InPolygon",
1318  /*0x71*/ "MergePoly",
1319  /*0x72*/ "SetDebug",
1320  /*0x73*/ "InspectObject", // for debugging
1321  /*0x74*/ "MemoryInfo",
1322  /*0x75*/ "Profiler", // for debugging
1323  /*0x76*/ "Record", // for debugging
1324  /*0x77*/ "PlayBack", // for debugging
1325  /*0x78*/ "MonoOut", // for debugging
1326  /*0x79*/ "SetFatalStr", // for debugging
1327  /*0x7a*/ "GetCWD",
1328  /*0x7b*/ "ValidPath",
1329  /*0x7c*/ "FileIO",
1330  /*0x7d*/ "Dummy",
1331  /*0x7e*/ "DeviceInfo",
1332  /*0x7f*/ "Palette",
1333  /*0x80*/ "PalVary",
1334  /*0x81*/ "PalCycle",
1335  /*0x82*/ "Array",
1336  /*0x83*/ "String",
1337  /*0x84*/ "RemapColors",
1338  /*0x85*/ "IntegrityChecking", // for debugging
1339  /*0x86*/ "CheckIntegrity", // for debugging
1340  /*0x87*/ "ObjectIntersect",
1341  /*0x88*/ "MarkMemory", // for debugging
1342  /*0x89*/ "TextWidth",
1343  /*0x8a*/ "PointSize",
1344 
1345  /*0x8b*/ "AddLine",
1346  /*0x8c*/ "DeleteLine",
1347  /*0x8d*/ "UpdateLine",
1348  /*0x8e*/ "AddPolygon",
1349  /*0x8f*/ "DeletePolygon",
1350  /*0x90*/ "UpdatePolygon",
1351  /*0x91*/ "Bitmap",
1352  /*0x92*/ "ScrollWindow",
1353  /*0x93*/ "SetFontRes",
1354  /*0x94*/ "MovePlaneItems",
1355  /*0x95*/ "PreloadResource",
1356  /*0x96*/ "Dummy",
1357  /*0x97*/ "ResourceTrack",
1358  /*0x98*/ "CheckCDisc",
1359  /*0x99*/ "GetSaveCDisc",
1360  /*0x9a*/ "TestPoly",
1361  /*0x9b*/ "WinHelp",
1362  /*0x9c*/ "LoadChunk",
1363  /*0x9d*/ "SetPalStyleRange",
1364  /*0x9e*/ "AddPicAt",
1365  /*0x9f*/ "MessageBox"
1366 };
1367 
1368 static const char *const sci21_default_knames[] = {
1369  /*0x00*/ "Load",
1370  /*0x01*/ "UnLoad",
1371  /*0x02*/ "ScriptID",
1372  /*0x03*/ "DisposeScript",
1373  /*0x04*/ "Lock",
1374  /*0x05*/ "ResCheck",
1375  /*0x06*/ "Purge",
1376  /*0x07*/ "SetLanguage",
1377  /*0x08*/ "Dummy",
1378  /*0x09*/ "Dummy",
1379  /*0x0a*/ "Clone",
1380  /*0x0b*/ "DisposeClone",
1381  /*0x0c*/ "RespondsTo",
1382  /*0x0d*/ "FindSelector",
1383  /*0x0e*/ "FindClass",
1384  /*0x0f*/ "Dummy",
1385  /*0x10*/ "Dummy",
1386  /*0x11*/ "Dummy",
1387  /*0x12*/ "Dummy",
1388  /*0x13*/ "Dummy",
1389  /*0x14*/ "SetNowSeen",
1390  /*0x15*/ "NumLoops",
1391  /*0x16*/ "NumCels",
1392  /*0x17*/ "IsOnMe",
1393  /*0x18*/ "AddMagnify", // dummy in SCI3
1394  /*0x19*/ "DeleteMagnify", // dummy in SCI3
1395  /*0x1a*/ "CelRect",
1396  /*0x1b*/ "BaseLineSpan",
1397  /*0x1c*/ "CelWide",
1398  /*0x1d*/ "CelHigh",
1399  /*0x1e*/ "AddScreenItem",
1400  /*0x1f*/ "DeleteScreenItem",
1401  /*0x20*/ "UpdateScreenItem",
1402  /*0x21*/ "FrameOut",
1403  /*0x22*/ "CelInfo",
1404  /*0x23*/ "Bitmap",
1405  /*0x24*/ "CelLink",
1406  /*0x25*/ "Dummy",
1407  /*0x26*/ "Dummy",
1408  /*0x27*/ "Dummy",
1409  /*0x28*/ "AddPlane",
1410  /*0x29*/ "DeletePlane",
1411  /*0x2a*/ "UpdatePlane",
1412  /*0x2b*/ "RepaintPlane",
1413  /*0x2c*/ "GetHighPlanePri",
1414  /*0x2d*/ "GetHighItemPri", // unused function
1415  /*0x2e*/ "SetShowStyle",
1416  /*0x2f*/ "ShowStylePercent", // unused function
1417  /*0x30*/ "SetScroll", // dummy in SCI3
1418  /*0x31*/ "MovePlaneItems",
1419  /*0x32*/ "ShakeScreen",
1420  /*0x33*/ "Dummy",
1421  /*0x34*/ "Dummy",
1422  /*0x35*/ "Dummy",
1423  /*0x36*/ "Dummy",
1424  /*0x37*/ "IsHiRes",
1425  /*0x38*/ "SetVideoMode",
1426  /*0x39*/ "ShowMovie", // dummy in SCI3
1427  /*0x3a*/ "Robot",
1428  /*0x3b*/ "CreateTextBitmap",
1429  /*0x3c*/ "Random",
1430  /*0x3d*/ "Abs",
1431  /*0x3e*/ "Sqrt",
1432  /*0x3f*/ "GetAngle",
1433  /*0x40*/ "GetDistance",
1434  /*0x41*/ "ATan",
1435  /*0x42*/ "SinMult",
1436  /*0x43*/ "CosMult",
1437  /*0x44*/ "SinDiv",
1438  /*0x45*/ "CosDiv",
1439  /*0x46*/ "Text",
1440  /*0x47*/ "Dummy",
1441  /*0x48*/ "Message",
1442  /*0x49*/ "Font",
1443  /*0x4a*/ "EditText",
1444  /*0x4b*/ "InputText",
1445  /*0x4c*/ "ScrollWindow", // Dummy in SCI3
1446  /*0x4d*/ "Dummy",
1447  /*0x4e*/ "Dummy",
1448  /*0x4f*/ "Dummy",
1449  /*0x50*/ "GetEvent",
1450  /*0x51*/ "GlobalToLocal",
1451  /*0x52*/ "LocalToGlobal",
1452  /*0x53*/ "MapKeyToDir",
1453  /*0x54*/ "HaveMouse",
1454  /*0x55*/ "SetCursor",
1455  /*0x56*/ "VibrateMouse", // Dummy in SCI3
1456  /*0x57*/ "Dummy",
1457  /*0x58*/ "Dummy",
1458  /*0x59*/ "Dummy",
1459  /*0x5a*/ "List",
1460  /*0x5b*/ "Array",
1461  /*0x5c*/ "String",
1462  /*0x5d*/ "FileIO",
1463  /*0x5e*/ "BaseSetter",
1464  /*0x5f*/ "DirLoop",
1465  /*0x60*/ "CantBeHere",
1466  /*0x61*/ "InitBresen",
1467  /*0x62*/ "DoBresen",
1468  /*0x63*/ "SetJump",
1469  /*0x64*/ "AvoidPath", // dummy in SCI3
1470  /*0x65*/ "InPolygon",
1471  /*0x66*/ "MergePoly", // dummy in SCI3
1472  /*0x67*/ "ObjectIntersect",
1473  /*0x68*/ "Dummy",
1474  /*0x69*/ "MemoryInfo",
1475  /*0x6a*/ "DeviceInfo",
1476  /*0x6b*/ "Palette",
1477  /*0x6c*/ "PalVary",
1478  /*0x6d*/ "PalCycle",
1479  /*0x6e*/ "RemapColors",
1480  /*0x6f*/ "AddLine",
1481  /*0x70*/ "DeleteLine",
1482  /*0x71*/ "UpdateLine",
1483  /*0x72*/ "AddPolygon",
1484  /*0x73*/ "DeletePolygon",
1485  /*0x74*/ "UpdatePolygon",
1486  /*0x75*/ "DoSound",
1487  /*0x76*/ "DoAudio",
1488  /*0x77*/ "DoSync",
1489  /*0x78*/ "Save",
1490  /*0x79*/ "GetTime",
1491  /*0x7a*/ "Platform",
1492  /*0x7b*/ "CD",
1493  /*0x7c*/ "SetQuitStr",
1494  /*0x7d*/ "GetConfig",
1495  /*0x7e*/ "Table",
1496  /*0x7f*/ "WinHelp", // Windows only
1497  /*0x80*/ "Dummy",
1498  /*0x81*/ "Empty", // called when clicking the On-line Help button in Phant2 control panel
1499  /*0x82*/ "Dummy",
1500  /*0x83*/ "PrintDebug", // debug function, used by Shivers (demo and full)
1501  /*0x84*/ "Dummy",
1502  /*0x85*/ "Dummy",
1503  /*0x86*/ "Dummy",
1504  /*0x87*/ "Dummy",
1505  /*0x88*/ "Dummy",
1506  /*0x89*/ "Dummy",
1507  /*0x8a*/ "LoadChunk",
1508  /*0x8b*/ "SetPalStyleRange",
1509  /*0x8c*/ "AddPicAt",
1510  /*0x8d*/ "Dummy", // MessageBox in SCI3
1511  /*0x8e*/ "NewRoom", // debug function
1512  /*0x8f*/ "Dummy",
1513  /*0x90*/ "Priority",
1514  /*0x91*/ "MorphOn",
1515  /*0x92*/ "PlayVMD",
1516  /*0x93*/ "SetHotRectangles",
1517  /*0x94*/ "MulDiv",
1518  /*0x95*/ "GetSierraProfileInt", // , Windows only
1519  /*0x96*/ "GetSierraProfileString", // , Windows only
1520  /*0x97*/ "SetWindowsOption", // Windows only
1521  /*0x98*/ "GetWindowsOption", // Windows only
1522  /*0x99*/ "WinDLL", // Windows only
1523  /*0x9a*/ "Dummy",
1524  /*0x9b*/ "Dummy", // Minimize in SCI3
1525  /*0x9c*/ "DeletePic",
1526  // == SCI3 only ===============
1527  /*0x9d*/ "Dummy",
1528  /*0x9e*/ "WebConnect",
1529  /*0x9f*/ "Dummy",
1530  /*0xa0*/ "PlayDuck",
1531  /*0xa1*/ "WinExec"
1532 };
1533 
1534 #endif
1535 
1536 // Base set of opcode formats. They're copied and adjusted slightly in
1537 // script_adjust_opcode_format depending on SCI version.
1538 static const opcode_format g_base_opcode_formats[128][4] = {
1539  // 00 - 03 / bnot, add, sub, mul
1540  {Script_None}, {Script_None}, {Script_None}, {Script_None},
1541  // 04 - 07 / div, mod, shr, shl
1542  {Script_None}, {Script_None}, {Script_None}, {Script_None},
1543  // 08 - 0B / xor, and, or, neg
1544  {Script_None}, {Script_None}, {Script_None}, {Script_None},
1545  // 0C - 0F / not, eq, ne, gt
1546  {Script_None}, {Script_None}, {Script_None}, {Script_None},
1547  // 10 - 13 / ge, lt, le, ugt
1548  {Script_None}, {Script_None}, {Script_None}, {Script_None},
1549  // 14 - 17 / uge, ult, ule, bt
1550  {Script_None}, {Script_None}, {Script_None}, {Script_SRelative},
1551  // 18 - 1B / bnt, jmp, ldi, push
1552  {Script_SRelative}, {Script_SRelative}, {Script_SVariable}, {Script_None},
1553  // 1C - 1F / pushi, toss, dup, link
1554  {Script_SVariable}, {Script_None}, {Script_None}, {Script_Variable},
1555  // 20 - 23 / call, callk, callb, calle
1556  {Script_SRelative, Script_Byte}, {Script_Variable, Script_Byte}, {Script_Variable, Script_Byte}, {Script_Variable, Script_SVariable, Script_Byte},
1557  // 24 - 27 / ret, send, dummy, dummy
1558  {Script_End}, {Script_Byte}, {Script_Invalid}, {Script_Invalid},
1559  // 28 - 2B / class, dummy, self, super
1560  {Script_Variable}, {Script_Invalid}, {Script_Byte}, {Script_Variable, Script_Byte},
1561  // 2C - 2F / rest, lea, selfID, dummy
1562  {Script_SVariable}, {Script_SVariable, Script_Variable}, {Script_None}, {Script_Invalid},
1563  // 30 - 33 / pprev, pToa, aTop, pTos
1564  {Script_None}, {Script_Property}, {Script_Property}, {Script_Property},
1565  // 34 - 37 / sTop, ipToa, dpToa, ipTos
1566  {Script_Property}, {Script_Property}, {Script_Property}, {Script_Property},
1567  // 38 - 3B / dpTos, lofsa, lofss, push0
1568  {Script_Property}, {Script_SRelative}, {Script_SRelative}, {Script_None},
1569  // 3C - 3F / push1, push2, pushSelf, line
1570  {Script_None}, {Script_None}, {Script_None}, {Script_Word},
1571  // ------------------------------------------------------------------------
1572  // 40 - 43 / lag, lal, lat, lap
1573  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1574  // 44 - 47 / lsg, lsl, lst, lsp
1575  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1576  // 48 - 4B / lagi, lali, lati, lapi
1577  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1578  // 4C - 4F / lsgi, lsli, lsti, lspi
1579  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1580  // ------------------------------------------------------------------------
1581  // 50 - 53 / sag, sal, sat, sap
1582  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1583  // 54 - 57 / ssg, ssl, sst, ssp
1584  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1585  // 58 - 5B / sagi, sali, sati, sapi
1586  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1587  // 5C - 5F / ssgi, ssli, ssti, sspi
1588  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1589  // ------------------------------------------------------------------------
1590  // 60 - 63 / plusag, plusal, plusat, plusap
1591  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1592  // 64 - 67 / plussg, plussl, plusst, plussp
1593  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1594  // 68 - 6B / plusagi, plusali, plusati, plusapi
1595  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1596  // 6C - 6F / plussgi, plussli, plussti, plusspi
1597  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1598  // ------------------------------------------------------------------------
1599  // 70 - 73 / minusag, minusal, minusat, minusap
1600  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1601  // 74 - 77 / minussg, minussl, minusst, minussp
1602  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1603  // 78 - 7B / minusagi, minusali, minusati, minusapi
1604  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param},
1605  // 7C - 7F / minussgi, minussli, minussti, minusspi
1606  {Script_Global}, {Script_Local}, {Script_Temp}, {Script_Param}
1607 };
1608 
1609 } // End of namespace Sci
1610 
1611 #endif // SCI_ENGINE_KERNEL_TABLES_H
SciVersion
Definition: detection.h:134
Definition: segment.h:202
Definition: kernel_tables.h:47
Definition: workarounds.h:49
Definition: controls32.h:145
Definition: object.h:69
Definition: view.h:29
Definition: console.h:28
Definition: kernel_tables.h:628
Definition: portrait.h:41
Definition: helpers.h:247
Definition: lobject.h:338
Platform
Definition: platform.h:46