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
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "agi/agi.h"
24 #include "agi/opcodes.h"
25
26 namespace Agi {
27
28 const AgiOpCodeDefinitionEntry opCodesV1Cond[] = {
29 { "", "", &condUnknown }, // 00
30 { "equaln", "vn", &condEqual }, // 01
31 { "equalv", "vv", &condEqualV }, // 02
32 { "lessn", "vn", &condLess }, // 03
33 { "lessv", "vv", &condLessV }, // 04
34 { "greatern", "vn", &condGreater }, // 05
35 { "greaterv", "vv", &condGreaterV }, // 06
36 { "isset", "v", &condIsSetV1 }, // 07
37 { "has", "n", &condHasV1 }, // 08
38 { "said", "nnnn", &condSaid2 }, // 09
39 { "posn", "nnnnn", &condPosn }, // 0A
40 { "controller", "n", &condController }, // 0B
41 { "obj.in.room", "nv", &condObjInRoom }, // 0C
42 { "said", "nnnnnn", &condSaid3 }, // 0D
43 { "have.key", "", &condHaveKey }, // 0E
44 { "said", "nn", &condSaid1 }, // 0F
45 { "bit", "nv", &condBit }, // 10
46 };
47
48 const AgiOpCodeDefinitionEntry opCodesV1[] = {
49 { "return", "", NULL }, // 00
50 { "increment", "v", &cmdIncrement }, // 01
51 { "decrement", "v", &cmdDecrement }, // 02
52 { "assignn", "vn", &cmdAssignN }, // 03
53 { "assignv", "vv", &cmdAssignV }, // 04
54 { "addn", "vn", &cmdAddN }, // 05
55 { "addv", "vv", &cmdAddV }, // 06
56 { "subn", "vn", &cmdSubN }, // 07
57 { "subv", "vv", &cmdSubV }, // 08
58 { "load.view", "n", &cmdLoadView }, // 09
59 { "animate.obj", "n", &cmdAnimateObj }, // 0A
60 { "new.room", "n", &cmdNewRoom }, // 0B
61 { "draw.pic", "v", &cmdDrawPicV1 }, // 0C
62 { "print", "s", &cmdPrint }, // 0D TODO
63 { "status", "", &cmdStatus }, // 0E TODO
64 { "save.game", "", &cmdSaveGame }, // 0F TODO
65 { "restore.game", "", &cmdLoadGame }, // 10 TODO
66 { "init.disk", "", &cmdInitDisk }, // 11 TODO
67 { "restart.game", "", &cmdRestartGame }, // 12 TODO
68 { "random", "v", &cmdRandomV1 }, // 13
69 { "get", "n", &cmdGetV1 }, // 14
70 { "drop", "n", &cmdDrop }, // 15
71 { "draw", "n", &cmdDraw }, // 16 TODO
72 { "erase", "n", &cmdErase }, // 17 TODO
73 { "position", "nnn", &cmdPositionV1 }, // 18
74 { "position.v", "nvv", &cmdPositionFV1 }, // 19
75 { "get.posn", "nvv", &cmdGetPosn }, // 1A
76 { "set.cel", "nn", &cmdSetCel }, // 1B
77 { "set.loop", "nn", &cmdSetLoop }, // 1C
78 { "end.of.loop", "nn", &cmdEndOfLoopV1 }, // 1D
79 { "reverse.loop", "nn", &cmdReverseLoopV1 }, // 1E
80 { "move.obj", "nnnnn", &cmdMoveObj }, // 1F
81 { "set.view", "nn", &cmdSetView }, // 20
82 { "follow.ego", "nnn", &cmdFollowEgo }, // 21
83 { "block", "", &cmdBlock }, // 22
84 { "unblock", "", &cmdUnblock }, // 23
85 { "ignore.blocks", "n", &cmdIgnoreBlocks }, // 24
86 { "observe.blocks", "n", &cmdObserveBlocks }, // 25
87 { "wander", "n", &cmdWander }, // 26
88 { "reposition", "nvv", &cmdRepositionV1 }, // 27
89 { "stop.motion", "n", &cmdStopMotionV1 }, // 28
90 { "start.motion", "n", &cmdStartMotionV1 }, // 29
91 { "stop.cycling", "n", &cmdStopCycling }, // 2A
92 { "start.cycling", "n", &cmdStartCycling }, // 2B
93 { "stop.update", "n", &cmdStopUpdate }, // 2C
94 { "start.update", "n", &cmdStartUpdate }, // 2D
95 { "program.control", "", &cmdProgramControl }, // 2E
96 { "player.control", "", &cmdPlayerControl }, // 2F
97 { "set.priority", "nn", &cmdSetPriority }, // 30
98 { "release.priority", "n", &cmdReleasePriority }, // 31
99 { "add.to.pic", "nnnnnn", &cmdAddToPicV1 }, // 32
100 { "set.horizon", "n", &cmdSetHorizon }, // 33
101 { "ignore.horizon", "n", &cmdIgnoreHorizon }, // 34
102 { "observe.horizon", "n", &cmdObserveHorizon }, // 35
103 { "load.logics", "n", &cmdLoadLogic }, // 36 TODO
104 { "object.on.water", "n", &cmdObjectOnWater }, // 37
105 { "load.pic", "v", &cmdLoadPicV1 }, // 38
106 { "load.sound", "n", &cmdLoadSound }, // 39
107 { "sound", "nn", &cmdSound }, // 3A
108 { "stop.sound", "", &cmdStopSound }, // 3B
109 { "set.v", "v", &cmdSetV }, // 3C
110 { "reset.v", "v", &cmdResetV }, // 3D
111 { "toggle.v", "v", &cmdToggleV }, // 3E
112 { "new.room.v", "v", &cmdNewRoom }, // 3F
113 { "call", "n", &cmdCallV1 }, // 40 TODO
114 { "quit", "", &cmdQuitV1 }, // 41
115 { "set.speed", "v", &cmdSetSpeed }, // 42
116 { "move.obj.v", "nvvvv", &cmdMoveObjF }, // 43
117 { "...", "nn", &cmdUnknown }, // 44
118 { "get.v", "v", &cmdUnknown }, // 45
119 { "assign.v", "vv", &cmdUnknown }, // 46
120 { "...", "n", &cmdUnknown }, // 47 # printvar.v
121 { "get.priority", "nv", &cmdGetPriority }, // 48
122 { "ignore.objs", "n", &cmdIgnoreObjs }, // 49
123 { "observe.objs", "n", &cmdObserveObjs }, // 4A
124 { "distance", "nnv", &cmdDistance }, // 4B
125 { "object.on.land", "n", &cmdObjectOnLand }, // 4C
126 { "...", "nv", &cmdUnknown }, // 4D # set.priority.f
127 { "...", "", &cmdUnknown }, // 4E # show.obj
128 { "load.logics", "n", &cmdLoadLogic }, // 4F # load.global.logics
129 { "display", "nnns", &cmdDisplay }, // 50 TODO: 4 vs 3 args
130 { "prevent.input???", "", &cmdUnknown }, // 51
131 { "...", "", &cmdUnknown }, // 52 # nop
132 { "...", "n", &cmdUnknown }, // 53 # text.screen
133 { "...", "", &cmdUnknown }, // 54 ???
134 { "stop.motion", "", &cmdStopMotion }, // 55 or force.update??
135 { "discard.view", "n", &cmdDiscardView }, // 56
136 { "discard.pic", "v", &cmdDiscardPic }, // 57
137 { "set.item.view", "nn", &cmdSetItemView }, // 58
138 { "...", "", &cmdUnknown }, // 59 # reverse.cycle
139 { "last.cel", "nv", &cmdLastCel }, // 5A
140 { "set.cel.v", "nv", &cmdSetCelF }, // 5B
141 { "...", "", &cmdUnknown }, // 5C # normal.cycle
142 { "load.view", "n", &cmdLoadView }, // 5D
143 { "...", "", &cmdUnknown }, // 5E
144 { "...", "", &cmdUnknown }, // 5F
145 { "setbit", "nv", &cmdUnknown }, // 60
146 { "...", "nv", &cmdUnknown }, // 61 # clearbit
147 };
148
149 AgiOpCodeDefinitionEntry opCodesV2Cond[] = {
150 { "", "", &condUnknown }, // 00
151 { "equaln", "vn", &condEqual }, // 01
152 { "equalv", "vv", &condEqualV }, // 02
153 { "lessn", "vn", &condLess }, // 03
154 { "lessv", "vv", &condLessV }, // 04
155 { "greatern", "vn", &condGreater }, // 05
156 { "greaterv", "vv", &condGreaterV }, // 06
157 { "isset", "n", &condIsSet }, // 07
158 { "issetv", "v", &condIsSetV }, // 08
159 { "has", "n", &condHas }, // 09
160 { "obj.in.room", "nv", &condObjInRoom}, // 0A
161 { "posn", "nnnnn", &condPosn }, // 0B
162 { "controller", "n", &condController }, // 0C
163 { "have.key", "", &condHaveKey}, // 0D
164 { "said", "", &condSaid }, // 0E
165 { "compare.strings", "ss", &condCompareStrings }, // 0F
166 { "obj.in.box", "nnnnn", &condObjInBox }, // 10
167 { "center.posn", "nnnnn", &condCenterPosn }, // 11
168 { "right.posn", "nnnnn", &condRightPosn }, // 12
169 { "in.motion.using.mouse", "", &condUnknown13 } // 13
170 };
171
172 AgiOpCodeDefinitionEntry opCodesV2[] = {
173 { "return", "", NULL }, // 00
174 { "increment", "v", &cmdIncrement }, // 01
175 { "decrement", "v", &cmdDecrement }, // 02
176 { "assignn", "vn", &cmdAssignN }, // 03
177 { "assignv", "vv", &cmdAssignV }, // 04
178 { "addn", "vn", &cmdAddN }, // 05
179 { "addv", "vv", &cmdAddV }, // 06
180 { "subn", "vn", &cmdSubN }, // 07
181 { "subv", "vv", &cmdSubV }, // 08
182 { "lindirectv", "vv", &cmdLindirectV }, // 09
183 { "lindirect", "vv", &cmdRindirect }, // 0A
184 { "lindirectn", "vn", &cmdLindirectN }, // 0B
185 { "set", "n", &cmdSet }, // 0C
186 { "reset", "n", &cmdReset }, // 0D
187 { "toggle", "n", &cmdToggle }, // 0E
188 { "set.v", "v", &cmdSetV }, // 0F
189 { "reset.v", "v", &cmdResetV }, // 10
190 { "toggle.v", "v", &cmdToggleV }, // 11
191 { "new.room", "n", &cmdNewRoom }, // 12
192 { "new.room.v", "v", &cmdNewRoomF }, // 13
193 { "load.logics", "n", &cmdLoadLogic }, // 14
194 { "load.logics.v", "v", &cmdLoadLogicF }, // 15
195 { "call", "n", &cmdCall }, // 16
196 { "call.v", "v", &cmdCallF }, // 17
197 { "load.pic", "v", &cmdLoadPic }, // 18
198 { "draw.pic", "v", &cmdDrawPic }, // 19
199 { "show.pic", "", &cmdShowPic }, // 1A
200 { "discard.pic", "v", &cmdDiscardPic }, // 1B
201 { "overlay.pic", "v", &cmdOverlayPic }, // 1C
202 { "show.pri.screen", "", &cmdShowPriScreen }, // 1D
203 { "load.view", "n", &cmdLoadView }, // 1E
204 { "load.view.v", "v", &cmdLoadViewF }, // 1F
205 { "discard.view", "n", &cmdDiscardView }, // 20
206 { "animate.obj", "n", &cmdAnimateObj }, // 21
207 { "unanimate.all", "", &cmdUnanimateAll }, // 22
208 { "draw", "n", &cmdDraw }, // 23
209 { "erase", "n", &cmdErase }, // 24
210 { "position", "nnn", &cmdPosition }, // 25
211 { "position.v", "nvv", &cmdPositionF }, // 26
212 { "get.posn", "nvv", &cmdGetPosn }, // 27
213 { "reposition", "nvv", &cmdReposition }, // 28
214 { "set.view", "nn", &cmdSetView }, // 29
215 { "set.view.v", "nv", &cmdSetViewF }, // 2A
216 { "set.loop", "nn", &cmdSetLoop }, // 2B
217 { "set.loop.v", "nv", &cmdSetLoopF }, // 2C
218 { "fix.loop", "n", &cmdFixLoop }, // 2D
219 { "release.loop", "n", &cmdReleaseLoop }, // 2E
220 { "set.cel", "nn", &cmdSetCel }, // 2F
221 { "set.cel.v", "nv", &cmdSetCelF }, // 30
222 { "last.cel", "nv", &cmdLastCel }, // 31
223 { "current.cel", "nv", &cmdCurrentCel }, // 32
224 { "current.loop", "nv", &cmdCurrentLoop }, // 33
225 { "current.view", "nv", &cmdCurrentView }, // 34
226 { "number.of.loops", "nv", &cmdNumberOfLoops }, // 35
227 { "set.priority", "nn", &cmdSetPriority }, // 36
228 { "set.priority.v", "nv", &cmdSetPriorityF }, // 37
229 { "release.priority", "n", &cmdReleasePriority }, // 38
230 { "get.priority", "nn", &cmdGetPriority }, // 39
231 { "stop.update", "n", &cmdStopUpdate }, // 3A
232 { "start.update", "n", &cmdStartUpdate }, // 3B
233 { "force.update", "n", &cmdForceUpdate }, // 3C
234 { "ignore.horizon", "n", &cmdIgnoreHorizon }, // 3D
235 { "observe.horizon", "n", &cmdObserveHorizon }, // 3E
236 { "set.horizon", "n", &cmdSetHorizon }, // 3F
237 { "object.on.water", "n", &cmdObjectOnWater }, // 40
238 { "object.on.land", "n", &cmdObjectOnLand }, // 41
239 { "object.on.anything", "n", &cmdObjectOnAnything }, // 42
240 { "ignore.objs", "n", &cmdIgnoreObjs }, // 43
241 { "observe.objs", "n", &cmdObserveObjs }, // 44
242 { "distance", "nnv", &cmdDistance }, // 45
243 { "stop.cycling", "n", &cmdStopCycling }, // 46
244 { "start.cycling", "n", &cmdStartCycling }, // 47
245 { "normal.cycle", "n", &cmdNormalCycle }, // 48
246 { "end.of.loop", "nn", &cmdEndOfLoop }, // 49
247 { "reverse.cycle", "n", &cmdReverseCycle }, // 4A
248 { "reverse.loop", "nn", &cmdReverseLoop }, // 4B
249 { "cycle.time", "nv", &cmdCycleTime }, // 4C
250 { "stop.motion", "n", &cmdStopMotion }, // 4D
251 { "start.motion", "n", &cmdStartMotion }, // 4E
252 { "step.size", "nv", &cmdStepSize }, // 4F
253 { "step.time", "nv", &cmdStepTime }, // 50
254 { "move.obj", "nnnnn", &cmdMoveObj }, // 51
255 { "move.obj.v", "nvvvv", &cmdMoveObjF }, // 52
256 { "follow.ego", "nnn", &cmdFollowEgo }, // 53
257 { "wander", "n", &cmdWander }, // 54
258 { "normal.motion", "n", &cmdNormalMotion }, // 55
259 { "set.dir", "nv", &cmdSetDir }, // 56
260 { "get.dir", "nv", &cmdGetDir }, // 57
261 { "ignore.blocks", "n", &cmdIgnoreBlocks }, // 58
262 { "observe.blocks", "n", &cmdObserveBlocks }, // 59
263 { "block", "nnnn", &cmdBlock }, // 5A
264 { "unblock", "", &cmdUnblock }, // 5B
265 { "get", "n", &cmdGet }, // 5C
266 { "get.v", "v", &cmdGetF }, // 5D
267 { "drop", "n", &cmdDrop }, // 5E
268 { "put", "nn", &cmdPut }, // 5F
269 { "put.v", "vv", &cmdPutF }, // 60
270 { "get.room.v", "vv", &cmdGetRoomF }, // 61
271 { "load.sound", "n", &cmdLoadSound }, // 62
272 { "sound", "nn", &cmdSound }, // 63
273 { "stop.sound", "", &cmdStopSound }, // 64
274 { "print", "s", &cmdPrint }, // 65
275 { "print.v", "v", &cmdPrintF }, // 66
276 { "display", "nns", &cmdDisplay }, // 67
277 { "display.v", "vvv", &cmdDisplayF }, // 68
278 { "clear.lines", "nns", &cmdClearLines }, // 69
279 { "text.screen", "", &cmdTextScreen }, // 6A
280 { "graphics", "", &cmdGraphics }, // 6B
281 { "set.cursor.char", "s", &cmdSetCursorChar }, // 6C
282 { "set.text.attribute", "nn", &cmdSetTextAttribute }, // 6D
283 { "shake.screen", "n", &cmdShakeScreen }, // 6E
284 { "configure.screen", "nnn", &cmdConfigureScreen }, // 6F
285 { "status.line.on", "", &cmdStatusLineOn }, // 70
286 { "status.line.off", "", &cmdStatusLineOff }, // 71
287 { "set.string", "ns", &cmdSetString }, // 72
288 { "get.string", "nsnnn", &cmdGetString }, // 73
289 { "word.to.string", "nn", &cmdWordToString }, // 74
290 { "parse", "n", &cmdParse }, // 75
291 { "get.num", "nv", &cmdGetNum }, // 76
292 { "prevent.input", "", &cmdPreventInput }, // 77
293 { "accept.input", "", &cmdAcceptInput }, // 78
294 { "set.key", "nnn", &cmdSetKey }, // 79
295 { "add.to.pic", "nnnnnnn", &cmdAddToPic }, // 7A
296 { "add.to.pic.v", "vvvvvvv", &cmdAddToPicF }, // 7B
297 { "status", "", &cmdStatus }, // 7C
298 { "save.game", "", &cmdSaveGame }, // 7D
299 { "restore.game", "", &cmdLoadGame }, // 7E
300 { "init.disk", "", &cmdInitDisk }, // 7F
301 { "restart.game", "", &cmdRestartGame }, // 80
302 { "show.obj", "n", &cmdShowObj }, // 81
303 { "random", "nnv", &cmdRandom }, // 82
304 { "program.control", "", &cmdProgramControl }, // 83
305 { "player.control", "", &cmdPlayerControl }, // 84
306 { "obj.status.v", "v", &cmdObjStatusF }, // 85
307 { "quit", "n", &cmdQuit }, // 86 0 args for AGI version 2.089
308 { "show.mem", "", &cmdShowMem }, // 87
309 { "pause", "", &cmdPause }, // 88
310 { "echo.line", "", &cmdEchoLine }, // 89
311 { "cancel.line", "", &cmdCancelLine }, // 8A
312 { "init.joy", "", &cmdInitJoy }, // 8B
313 { "toggle.monitor", "", &cmdToggleMonitor }, // 8C
314 { "version", "", &cmdVersion }, // 8D
315 { "script.size", "n", &cmdScriptSize }, // 8E
316 { "set.game.id", "s", &cmdSetGameID }, // 8F
317 { "log", "s", &cmdLog }, // 90
318 { "set.scan.start", "", &cmdSetScanStart }, // 91
319 { "reset.scan.start", "", &cmdResetScanStart }, // 92
320 { "reposition.to", "nnn", &cmdRepositionTo }, // 93
321 { "reposition.to.v", "nvv", &cmdRepositionToF }, // 94
322 { "trace.on", "", &cmdTraceOn }, // 95
323 { "trace.info", "nnn", &cmdTraceInfo }, // 96
324 { "print.at", "snnn", &cmdPrintAt }, // 3 args for AGI versions before 2.440
325 { "print.at.v", "vnnn", &cmdPrintAtV }, // 98
326 { "discard.view.v", "v", &cmdDiscardView}, // 99
327 { "clear.text.rect", "nnnnn", &cmdClearTextRect }, // 9A
328 { "set.upper.left", "nn", &cmdSetUpperLeft }, // 9B
329 { "set.menu", "s", &cmdSetMenu }, // 9C
330 { "set.menu.item", "sn", &cmdSetMenuItem }, // 9D
331 { "submit.menu", "", &cmdSubmitMenu }, // 9E
332 { "enable.item", "n", &cmdEnableItem }, // 9F
333 { "disable.item", "n", &cmdDisableItem }, // A0
334 { "menu.input", "", &cmdMenuInput }, // A1
335 { "show.obj.v", "v", &cmdShowObjV }, // A2
336 { "open.dialogue", "", &cmdOpenDialogue }, // A3
337 { "close.dialogue", "", &cmdCloseDialogue }, // A4
338 { "mul.n", "vn", &cmdMulN }, // A5
339 { "mul.v", "vv", &cmdMulV }, // A6
340 { "div.n", "vn", &cmdDivN }, // A7
341 { "div.v", "vv", &cmdDivV }, // A8
342 { "close.window", "", &cmdCloseWindow }, // A9
343 { "set.simple", "n", &cmdSetSimple }, // AA AGI2.425+, *BUT* not included in AGI2.440
344 { "push.script", "", &cmdPushScript }, // AB
345 { "pop.script", "", &cmdPopScript }, // AC
346 { "hold.key", "", &cmdHoldKey }, // AD
347 { "set.pri.base", "n", &cmdSetPriBase }, // AE AGI2.936+ *AND* also inside AGI2.425
348 { "discard.sound", "n", &cmdDiscardSound }, // AF was skip for PC
349 { "hide.mouse", "", &cmdHideMouse }, // B0 1 arg for AGI version 3.002.086 AGI3+ only starts here
350 { "allow.menu", "n", &cmdAllowMenu }, // B1
351 { "show.mouse", "", &cmdShowMouse }, // B2
352 { "fence.mouse", "nnnn", &cmdFenceMouse }, // B3
353 { "mouse.posn", "vv", &cmdMousePosn }, // B4
354 { "release.key", "", &cmdReleaseKey }, // B5 2 args for at least the Amiga GR (v2.05 1989-03-09) using AGI 2.316
355 { "adj.ego.move.to.xy", "", &cmdAdjEgoMoveToXY } // B6
356 };
357
358 //
359 // Currently, there is no known difference between v3.002.098 -> v3.002.149
360 // So version emulated;
361 // 0x0086,
362 // 0x0149
363 //
364
setupOpCodes(uint16 version)365 void AgiEngine::setupOpCodes(uint16 version) {
366 const AgiOpCodeDefinitionEntry *opCodesTable = nullptr;
367 const AgiOpCodeDefinitionEntry *opCodesCondTable = nullptr;
368 uint16 opCodesTableSize = 0;
369 uint16 opCodesCondTableSize = 0;
370 uint16 opCodesTableMaxSize = sizeof(_opCodes) / sizeof(AgiOpCodeEntry);
371 uint16 opCodesCondTableMaxSize = sizeof(_opCodesCond) / sizeof(AgiOpCodeEntry);
372
373 debug(0, "Setting up for version 0x%04X", version);
374
375 if (version >= 0x2000) {
376 opCodesTable = opCodesV2;
377 opCodesCondTable = opCodesV2Cond;
378 opCodesTableSize = ARRAYSIZE(opCodesV2);
379 opCodesCondTableSize = ARRAYSIZE(opCodesV2Cond);
380 } else {
381 opCodesTable = opCodesV1;
382 opCodesCondTable = opCodesV1Cond;
383 opCodesTableSize = ARRAYSIZE(opCodesV1);
384 opCodesCondTableSize = ARRAYSIZE(opCodesV1Cond);
385 }
386
387 // copy data over
388 for (int opCodeNr = 0; opCodeNr < opCodesTableSize; opCodeNr++) {
389 _opCodes[opCodeNr].name = opCodesTable[opCodeNr].name;
390 _opCodes[opCodeNr].parameters = opCodesTable[opCodeNr].parameters;
391 _opCodes[opCodeNr].functionPtr = opCodesTable[opCodeNr].functionPtr;
392 }
393
394 for (int opCodeNr = 0; opCodeNr < opCodesCondTableSize; opCodeNr++) {
395 _opCodesCond[opCodeNr].name = opCodesCondTable[opCodeNr].name;
396 _opCodesCond[opCodeNr].parameters = opCodesCondTable[opCodeNr].parameters;
397 _opCodesCond[opCodeNr].functionPtr = opCodesCondTable[opCodeNr].functionPtr;
398 }
399
400 // Alter opcode parameters for specific games
401 if ((version >= 0x2000) && (version < 0x3000)) {
402 // AGI3 adjustments
403
404 // 'quit' takes 0 args for 2.089
405 if (version == 0x2089)
406 _opCodes[0x86].parameters = "";
407
408 // 'print.at' and 'print.at.v' take 3 args before 2.272
409 // This is documented in the specs as only < 2.440, but it seems
410 // that KQ3 (2.272) needs a 'print.at' taking 4 args.
411 if (version < 0x2272) {
412 _opCodes[0x97].parameters = "vvv";
413 _opCodes[0x98].parameters = "vvv";
414 }
415 }
416
417 if (version >= 0x3000) {
418 // AGI3 adjustments
419 // 'unknown176' takes 1 arg for 3.002.086, not 0 args.
420 // 'unknown173' also takes 1 arg for 3.002.068, not 0 args.
421 // Is this actually used anywhere? -- dsymonds
422 if (version == 0x3086) {
423 _opCodes[0xb0].parameters = "n";
424 _opCodes[0xad].parameters = "n";
425 }
426 }
427
428 // TODO: This could be either turned into a game feature, or a version
429 // specific check, instead of a game version check
430 // The Apple IIGS versions of MH1 and Goldrush both have a parameter for
431 // show.mouse and hide.mouse. Fixes bugs #6161 and #5885.
432 if ((getGameID() == GID_MH1 || getGameID() == GID_GOLDRUSH) &&
433 getPlatform() == Common::kPlatformApple2GS) {
434 _opCodes[176].parameters = "n"; // hide.mouse
435 _opCodes[178].parameters = "n"; // show.mouse
436 }
437
438 // FIXME: Apply this fix to other games also that use 2 arguments for command 182.
439 // 'adj.ego.move.to.x.y' (i.e. command 182) takes 2 arguments for at least the
440 // Amiga Gold Rush! (v2.05 1989-03-09) using Amiga AGI 2.316. Amiga's Gold Rush
441 // has been set to use AGI 3.149 in ScummVM so that's why this initialization is
442 // here and not in setupV2Game.
443 if (getGameID() == GID_GOLDRUSH && getPlatform() == Common::kPlatformAmiga)
444 _opCodes[182].parameters = "vv";
445
446 // add invalid entries for every opcode, that is not defined at all
447 for (int opCodeNr = opCodesTableSize; opCodeNr < opCodesTableMaxSize; opCodeNr++) {
448 _opCodes[opCodeNr].name = "illegal";
449 _opCodes[opCodeNr].parameters = "";
450 _opCodes[opCodeNr].functionPtr = nullptr;
451 }
452
453 for (int opCodeNr = opCodesCondTableSize; opCodeNr < opCodesCondTableMaxSize; opCodeNr++) {
454 _opCodesCond[opCodeNr].name = "illegal";
455 _opCodesCond[opCodeNr].parameters = "";
456 _opCodesCond[opCodeNr].functionPtr = nullptr;
457 }
458
459 // calculate parameter size
460 for (int opCodeNr = 0; opCodeNr < opCodesTableSize; opCodeNr++) {
461 _opCodes[opCodeNr].parameterSize = strlen( _opCodes[opCodeNr].parameters);
462 }
463
464 for (int opCodeNr = 0; opCodeNr < opCodesCondTableSize; opCodeNr++) {
465 _opCodesCond[opCodeNr].parameterSize = strlen( _opCodesCond[opCodeNr].parameters);
466 }
467 }
468
469 } // End of namespace Agi
470