Ticket #9103: descumm.cpp

File descumm.cpp, 79.9 KB (added by SF/jestar_jokin, 14 years ago)

source in case the diff doesn't work

Line 
1/* DeScumm - Scumm Script Disassembler (version 2-5 scripts)
2 * Copyright (C) 2001 Ludvig Strigeus
3 * Copyright (C) 2002-2006 The ScummVM Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/trunk/descumm.cpp $
20 * $Id: descumm.cpp 45339 2009-10-22 19:48:20Z fingolfin $
21 *
22 */
23
24#include "descumm.h"
25
26/*
27 Similar to the code that detects "head" while loops like this:
28 while(Condition) {
29 }
30 add code to detect tail while loops, i.e. something of the kind
31 do {
32 } while(Condition);
33 In V2-V5, those are the most frequent type of loops (and in V6-V8 they
34 sometimes occur, too).
35
36 However, implementing this might be quite tricky, and require us to refactor the
37 code, because unlike a "head if/while", we don't know we are inside a loop until its
38 end. This means a problem for indention, and when outputing the initial "do {".
39 To solve this, we could implement some sort of look ahead; but that would be very
40 complicated, because essentially we have to perform full parsing of the data anyway.
41 Instead of doing multiple look aheads, one could also do a 2 pass descumming:
42 In pass 1, we find all jump statement, and identify all jump targets. From this data
43 we can work backwards to detect all loops (and also if/else/elsif).
44 Yet another approach would be to not emit any lines until we fully descummed the script.
45 Instead, we keep each line in a line buffer, with indention but with an associated
46 "indention" variable. When we discover a do/while loop, we can then insert a "do {"
47 line and increase the indention of all intermediate lines. However this approach
48 needs a lot of memory, and won't output anything until the script is fully descummed,
49 which is annoying when debugging descumm.
50
51*/
52
53enum TokenType {
54 TOK_BYTE = 1,
55 TOK_WORD = 2,
56 TOK_VAR = 3,
57 TOK_LIST = 4,
58 TOK_ASCII = 5,
59 TOK_CHAR = 6
60};
61
62
63#define A1B (TOK_BYTE<<0)
64#define A1W (TOK_WORD<<0)
65#define A1V (TOK_VAR<<0)
66#define A1LIST (TOK_LIST<<0)
67#define A1ASCII (TOK_ASCII<<0)
68
69#define A2B (TOK_BYTE<<4)
70#define A2W (TOK_WORD<<4)
71#define A2V (TOK_VAR<<4)
72#define A2LIST (TOK_LIST<<4)
73#define A2ASCII (TOK_ASCII<<4)
74
75#define A3B (TOK_BYTE<<8)
76#define A3W (TOK_WORD<<8)
77#define A3V (TOK_VAR<<8)
78#define A3LIST (TOK_LIST<<8)
79#define A3ASCII (TOK_ASCII<<8)
80#define A3CHAR (TOK_CHAR<<8)
81
82#define A4B (TOK_BYTE<<12)
83#define A4W (TOK_WORD<<12)
84#define A4V (TOK_VAR<<12)
85#define A4LIST (TOK_LIST<<12)
86#define A4ASCII (TOK_ASCII<<12)
87#define A4CHAR (TOK_CHAR<<12)
88
89#define A5ASCII (TOK_ASCII<<16)
90
91#define ATO (1<<31)
92#define ANOLASTPAREN (1<<30)
93#define ANOFIRSTPAREN (1<<29)
94#define ASTARTCOMMA (1<<28)
95#define AVARSTORE (1<<27)
96#define ANOENDSEMICOLON (1<<26)
97#define ATOWITHLASTPAREN (1<<25)
98
99
100void emit_if(char *buf, char *condition);
101
102
103const char *var_names0[] = {
104 /* 0 */
105 "VAR_EGO",
106 "VAR_RESULT",
107 "VAR_CAMERA_POS_X",
108 "VAR_HAVE_MSG",
109 /* 4 */
110 "VAR_ROOM",
111 "VAR_ACTIVE_ACTOR",
112 "VAR_OVERRIDE",
113 NULL,
114 /* 8 */
115 "VAR_IS_SOUND_RUNNING",
116 "VAR_ACTIVE_VERB",
117 "VAR_CHARCOUNT",
118 NULL
119};
120
121const char *var_names2[] = {
122 /* 0 */
123 "VAR_EGO",
124 "VAR_RESULT",
125 "VAR_CAMERA_POS_X",
126 "VAR_HAVE_MSG",
127 /* 4 */
128 "VAR_ROOM",
129 "VAR_OVERRIDE",
130 "VAR_MACHINE_SPEED",
131 "VAR_CHARCOUNT",
132 /* 8 */
133 "VAR_ACTIVE_VERB",
134 "VAR_ACTIVE_OBJECT1",
135 "VAR_ACTIVE_OBJECT2",
136 "VAR_NUM_ACTOR",
137 /* 12 */
138 "VAR_CURRENT_LIGHTS",
139 "VAR_CURRENTDRIVE",
140 NULL,
141 NULL,
142 /* 16 */
143 NULL,
144 "VAR_MUSIC_TIMER",
145 "VAR_VERB_ALLOWED",
146 "VAR_ACTOR_RANGE_MIN",
147 /* 20 */
148 "VAR_ACTOR_RANGE_MAX",
149 NULL,
150 NULL,
151 "VAR_CAMERA_MIN_X",
152 /* 24 */
153 "VAR_CAMERA_MAX_X",
154 "VAR_TIMER_NEXT",
155 "VAR_SENTENCE_VERB",
156 "VAR_SENTENCE_OBJECT1",
157 /* 28 */
158 "VAR_SENTENCE_OBJECT2",
159 "VAR_SENTENCE_PREPOSITION",
160 "VAR_VIRT_MOUSE_X",
161 "VAR_VIRT_MOUSE_Y",
162 /* 32 */
163 "VAR_CLICK_AREA",
164 "VAR_CLICK_VERB",
165 NULL,
166 "VAR_CLICK_OBJECT",
167 /* 36 */
168 "VAR_ROOM_RESOURCE",
169 "VAR_LAST_SOUND",
170 "VAR_BACKUP_VERB",
171 "VAR_KEYPRESS",
172 /* 40 */
173 "VAR_CUTSCENEEXIT_KEY",
174 "VAR_TALK_ACTOR",
175 NULL,
176 NULL
177};
178
179const char *var_names3[] = {
180 /* 0 */
181 "VAR_RESULT",
182 "VAR_EGO",
183 "VAR_CAMERA_POS_X",
184 "VAR_HAVE_MSG",
185 /* 4 */
186 "VAR_ROOM",
187 "VAR_OVERRIDE",
188 "VAR_MACHINE_SPEED",
189 "VAR_ME",
190 /* 8 */
191 "VAR_NUM_ACTOR",
192 "VAR_CURRENT_LIGHTS",
193 "VAR_CURRENTDRIVE",
194 "VAR_TMR_1",
195 /* 12 */
196 "VAR_TMR_2",
197 "VAR_TMR_3",
198 "VAR_MUSIC_TIMER",
199 "VAR_ACTOR_RANGE_MIN",
200 /* 16 */
201 "VAR_ACTOR_RANGE_MAX",
202 "VAR_CAMERA_MIN_X",
203 "VAR_CAMERA_MAX_X",
204 "VAR_TIMER_NEXT",
205 /* 20 */
206 "VAR_VIRT_MOUSE_X",
207 "VAR_VIRT_MOUSE_Y",
208 "VAR_ROOM_RESOURCE",
209 "VAR_LAST_SOUND",
210 /* 24 */
211 "VAR_CUTSCENEEXIT_KEY",
212 "VAR_TALK_ACTOR",
213 "VAR_CAMERA_FAST_X",
214 NULL,
215 /* 28 */
216 "VAR_ENTRY_SCRIPT",
217 "VAR_ENTRY_SCRIPT2",
218 "VAR_EXIT_SCRIPT",
219 "VAR_EXIT_SCRIPT2",
220 /* 32 */
221 "VAR_VERB_SCRIPT",
222 "VAR_SENTENCE_SCRIPT",
223 "VAR_INVENTORY_SCRIPT",
224 "VAR_CUTSCENE_START_SCRIPT",
225 /* 36 */
226 "VAR_CUTSCENE_END_SCRIPT",
227 "VAR_CHARINC",
228 "VAR_WALKTO_OBJ",
229 NULL,
230 /* 40 */
231 NULL,
232 NULL,
233 "VAR_RESTART_KEY",
234 "VAR_PAUSE_KEY",
235 /* 44 */
236 "VAR_MOUSE_X",
237 "VAR_MOUSE_Y",
238 "VAR_TIMER",
239 "VAR_TIMER_TOTAL",
240 /* 48 */
241 "VAR_SOUNDCARD",
242 "VAR_VIDEOMODE",
243 NULL,
244 NULL
245};
246
247const char *var_names4[] = {
248 /* 0 */
249 "VAR_RESULT",
250 "VAR_EGO",
251 "VAR_CAMERA_POS_X",
252 "VAR_HAVE_MSG",
253 /* 4 */
254 "VAR_ROOM",
255 "VAR_OVERRIDE",
256 "VAR_MACHINE_SPEED",
257 "VAR_ME",
258 /* 8 */
259 "VAR_NUM_ACTOR",
260 "VAR_CURRENT_LIGHTS",
261 "VAR_CURRENTDRIVE",
262 "VAR_TMR_1",
263 /* 12 */
264 "VAR_TMR_2",
265 "VAR_TMR_3",
266 "VAR_MUSIC_TIMER",
267 "VAR_ACTOR_RANGE_MIN",
268 /* 16 */
269 "VAR_ACTOR_RANGE_MAX",
270 "VAR_CAMERA_MIN_X",
271 "VAR_CAMERA_MAX_X",
272 "VAR_TIMER_NEXT",
273 /* 20 */
274 "VAR_VIRT_MOUSE_X",
275 "VAR_VIRT_MOUSE_Y",
276 "VAR_ROOM_RESOURCE",
277 "VAR_LAST_SOUND",
278 /* 24 */
279 "VAR_CUTSCENEEXIT_KEY",
280 "VAR_TALK_ACTOR",
281 "VAR_CAMERA_FAST_X",
282 "VAR_SCROLL_SCRIPT",
283 /* 28 */
284 "VAR_ENTRY_SCRIPT",
285 "VAR_ENTRY_SCRIPT2",
286 "VAR_EXIT_SCRIPT",
287 "VAR_EXIT_SCRIPT2",
288 /* 32 */
289 "VAR_VERB_SCRIPT",
290 "VAR_SENTENCE_SCRIPT",
291 "VAR_INVENTORY_SCRIPT",
292 "VAR_CUTSCENE_START_SCRIPT",
293 /* 36 */
294 "VAR_CUTSCENE_END_SCRIPT",
295 "VAR_CHARINC",
296 "VAR_WALKTO_OBJ",
297 "VAR_DEBUGMODE",
298 /* 40 */
299 "VAR_HEAPSPACE",
300 NULL,
301 "VAR_RESTART_KEY",
302 "VAR_PAUSE_KEY",
303 /* 44 */
304 "VAR_MOUSE_X",
305 "VAR_MOUSE_Y",
306 "VAR_TIMER",
307 "VAR_TIMER_TOTAL",
308 /* 48 */
309 "VAR_SOUNDCARD",
310 "VAR_VIDEOMODE",
311 "VAR_MAINMENU_KEY",
312 "VAR_FIXEDDISK",
313 /* 52 */
314 "VAR_CURSORSTATE",
315 "VAR_USERPUT",
316 "VAR_V5_TALK_STRING_Y",
317 /* Loom CD specific */
318 NULL,
319 /* 56 */
320 NULL,
321 NULL,
322 NULL,
323 NULL,
324 /* 60 */
325 "VAR_NOSUBTITLES",
326 NULL,
327 NULL,
328 NULL,
329 /* 64 */
330 "VAR_SOUNDPARAM",
331 "VAR_SOUNDPARAM2",
332 "VAR_SOUNDPARAM3",
333 NULL
334};
335
336const char *var_names5[] = {
337 /* 0 */
338 "VAR_RESULT",
339 "VAR_EGO",
340 "VAR_CAMERA_POS_X",
341 "VAR_HAVE_MSG",
342 /* 4 */
343 "VAR_ROOM",
344 "VAR_OVERRIDE",
345 "VAR_MACHINE_SPEED",
346 "VAR_ME",
347 /* 8 */
348 "VAR_NUM_ACTOR",
349 "VAR_CURRENT_LIGHTS",
350 "VAR_CURRENTDRIVE",
351 "VAR_TMR_1",
352 /* 12 */
353 "VAR_TMR_2",
354 "VAR_TMR_3",
355 "VAR_MUSIC_TIMER",
356 "VAR_ACTOR_RANGE_MIN",
357 /* 16 */
358 "VAR_ACTOR_RANGE_MAX",
359 "VAR_CAMERA_MIN_X",
360 "VAR_CAMERA_MAX_X",
361 "VAR_TIMER_NEXT",
362 /* 20 */
363 "VAR_VIRT_MOUSE_X",
364 "VAR_VIRT_MOUSE_Y",
365 "VAR_ROOM_RESOURCE",
366 "VAR_LAST_SOUND",
367 /* 24 */
368 "VAR_CUTSCENEEXIT_KEY",
369 "VAR_TALK_ACTOR",
370 "VAR_CAMERA_FAST_X",
371 "VAR_SCROLL_SCRIPT",
372 /* 28 */
373 "VAR_ENTRY_SCRIPT",
374 "VAR_ENTRY_SCRIPT2",
375 "VAR_EXIT_SCRIPT",
376 "VAR_EXIT_SCRIPT2",
377 /* 32 */
378 "VAR_VERB_SCRIPT",
379 "VAR_SENTENCE_SCRIPT",
380 "VAR_INVENTORY_SCRIPT",
381 "VAR_CUTSCENE_START_SCRIPT",
382 /* 36 */
383 "VAR_CUTSCENE_END_SCRIPT",
384 "VAR_CHARINC",
385 "VAR_WALKTO_OBJ",
386 "VAR_DEBUGMODE",
387 /* 40 */
388 "VAR_HEAPSPACE",
389 NULL,
390 "VAR_RESTART_KEY",
391 "VAR_PAUSE_KEY",
392 /* 44 */
393 "VAR_MOUSE_X",
394 "VAR_MOUSE_Y",
395 "VAR_TIMER",
396 "VAR_TIMER_TOTAL",
397 /* 48 */
398 "VAR_SOUNDCARD",
399 "VAR_VIDEOMODE",
400 "VAR_MAINMENU_KEY",
401 "VAR_FIXEDDISK",
402 /* 52 */
403 "VAR_CURSORSTATE",
404 "VAR_USERPUT",
405 NULL,
406 NULL,
407 /* 56 */
408 "VAR_SOUNDRESULT",
409 "VAR_TALKSTOP_KEY",
410 NULL,
411 "VAR_FADE_DELAY",
412 /* 60 */
413 "VAR_NOSUBTITLES",
414 NULL,
415 NULL,
416 NULL,
417 /* 64 */
418 "VAR_SOUNDPARAM",
419 "VAR_SOUNDPARAM2",
420 "VAR_SOUNDPARAM3",
421 "VAR_INPUTMODE",
422 /* 68 */
423 "VAR_MEMORY_PERFORMANCE",
424 "VAR_VIDEO_PERFORMANCE",
425 "VAR_ROOM_FLAG",
426 "VAR_GAME_LOADED",
427 /* 72 */
428 "VAR_NEW_ROOM",
429 NULL,
430 NULL,
431 NULL,
432 /* 76 */
433 NULL,
434 NULL,
435 NULL,
436 NULL
437};
438
439
440const char *get_num_string(int i) {
441 const char *s;
442
443 if (i & 0x8000) { /* Bit var */
444 i &= 0xFFF;
445 if (i >= 0x800)
446 s = "??Bit??";
447 else
448 s = "Bit";
449 } else if (i & 0x4000) {
450 i &= g_options.IndyFlag ? 0xF : 0xFFF;
451 if (i > 0x10)
452 s = "??Local??";
453 else
454 s = "Local";
455 } else {
456 i &= 0xFFF;
457 if (i >= 0x320)
458 s = "??Var??";
459 else
460 s = "Var";
461 }
462
463 if (g_options.haltOnError && (s[0] == '?')) {
464 error("%s out of range, was %d", s, i);
465 }
466
467 return s;
468}
469
470
471char *get_var(char *buf) {
472 int i;
473
474 if (g_options.scriptVersion <= 2)
475 i = get_byte();
476 else
477 i = (uint16)get_word();
478
479 assert(i >= 0);
480
481 if (g_options.scriptVersion >= 5 &&
482 i < ARRAYSIZE(var_names5) && var_names5[i]) {
483 buf += sprintf(buf, var_names5[i]);
484 return buf;
485 } else if (g_options.scriptVersion >= 4 &&
486 i < ARRAYSIZE(var_names4) && var_names4[i]) {
487 buf += sprintf(buf, var_names4[i]);
488 return buf;
489 } else if (g_options.scriptVersion >= 3 &&
490 i < ARRAYSIZE(var_names3) && var_names3[i]) {
491 buf += sprintf(buf, var_names3[i]);
492 return buf;
493 } else if (g_options.scriptVersion >= 1 &&
494 i < ARRAYSIZE(var_names2) && var_names2[i]) {
495 buf += sprintf(buf, var_names2[i]);
496 return buf;
497 } else if (g_options.scriptVersion == 0 &&
498 i < ARRAYSIZE(var_names0) && var_names0[i]) {
499 buf += sprintf(buf, var_names0[i]);
500 return buf;
501 } else if (g_options.scriptVersion <= 2 && g_options.ZakFlag && (i == 234 || i == 235)) {
502 buf += sprintf(buf, (i == 234) ? "ZERO" : "ONE");
503 return buf;
504 } else if ((i & 0x8000) && (g_options.GF_UNBLOCKED || g_options.ZakFlag))
505 buf += sprintf(buf, "Var[%d Bit %d", (i & 0x0FFF) >> 4, i & 0x000F);
506 else
507 buf += sprintf(buf, "%s[%d", get_num_string(i), i & 0xFFF);
508
509 if (i & 0x2000) {
510 int j = get_word();
511 if (j & 0x2000) {
512 j ^= 0x2000;
513 sprintf(buf, " + %s[%d]", get_num_string(j), j & 0xFFF);
514 } else
515 sprintf(buf, " + %d", j & 0xFFF);
516 }
517 strcat(buf, "]");
518
519 return strchr(buf, 0);
520
521}
522
523char *get_var_or_word(char *buf, char condition) {
524 if (condition)
525 get_var(buf);
526 else
527 sprintf(buf, "%d", get_word());
528 return strchr(buf, 0);
529}
530
531char *get_var_or_byte(char *buf, char condition) {
532 if (condition)
533 get_var(buf);
534 else
535 sprintf(buf, "%d", get_byte());
536 return strchr(buf, 0);
537}
538
539char *get_list(char *buf) {
540 int i;
541 int j = 0;
542 bool first = true;
543
544 buf = strecpy(buf, "[");
545 do {
546 i = get_byte();
547 if (i == 0xFF)
548 break;
549 if (!first)
550 buf = strecpy(buf, ",");
551 first = false;
552 buf = get_var_or_word(buf, i & 0x80);
553 j++;
554 if (j > 16) {
555 printf("ERROR: too many variables in argument list!\n");
556 if (g_options.haltOnError)
557 exit(1);
558 break;
559 }
560 } while (1);
561
562 return strecpy(buf, "]");
563}
564
565char *putascii(char *buf, int i) {
566 if (i > 31 && i < 128) {
567 // non-printable chars are escaped by backslashes as so: "\x00"
568 // backslashes and quote marks are escaped like so: "\\" "\""
569 if (i == '\\' || i == '"') {
570 buf[0] = '\\';
571 buf++;
572 }
573 buf[0] = i;
574 buf[1] = 0;
575 return buf + 1;
576 }
577 return buf + sprintf(buf, "\\x%.2X", i);
578}
579
580char *get_ascii(char *buf) {
581 int i;
582
583 buf = strecpy(buf, "\"");
584
585 do {
586 i = get_byte();
587 if (!i)
588 break;
589 buf = putascii(buf, i);
590 if (i == 255) {
591 i = get_byte();
592 buf = putascii(buf, i);
593
594 // Workaround for a script bug in Indy3
595 if (i == 46 && g_options.scriptVersion == 3 && g_options.IndyFlag)
596 continue;
597
598 if (i != 1 && i != 2 && i != 3 && i != 8) {
599 buf = putascii(buf, get_byte());
600 buf = putascii(buf, get_byte());
601 }
602 }
603 } while (1);
604
605 return strecpy(buf, "\"");
606}
607
608
609
610char *add_a_tok(char *buf, int type) {
611 switch (type) {
612 case TOK_BYTE:
613 buf += sprintf(buf, "%d", get_byte());
614 break;
615 case TOK_WORD:
616 buf += sprintf(buf, "%d", get_word());
617 break;
618 case TOK_VAR:
619 buf = get_var(buf);
620 break;
621 case TOK_LIST:
622 buf = get_list(buf);
623 break;
624 case TOK_ASCII:
625 buf = get_ascii(buf);
626 break;
627 case TOK_CHAR:
628 error("this code seems to be dead");
629 buf = putascii(buf, get_byte());
630 break;
631 }
632 return buf;
633}
634
635char *do_tok(char *buf, const char *text, int args) {
636 char *buforg = buf;
637
638
639 if (args & AVARSTORE) {
640 buf = get_var(buf);
641 buf = strecpy(buf, " = ");
642 }
643
644 if (text)
645 buf = strecpy(buf, text);
646
647 if (!(args & ANOFIRSTPAREN))
648 buf = strecpy(buf, "(");
649
650 if (args & ASTARTCOMMA)
651 buf = strecpy(buf, ",");
652
653 if (args & 0xF) {
654 buf = add_a_tok(buf, args & 0xF);
655 if (args & 0xF0) {
656 buf = add_a_tok(strecpy(buf, ","), (args >> 4) & 0xF);
657 if (args & 0xF00) {
658 buf = add_a_tok(strecpy(buf, ","), (args >> 8) & 0xF);
659 if (args & 0xF000) {
660 buf = add_a_tok(strecpy(buf, ","), (args >> 12) & 0xF);
661 if (args & 0xF0000)
662 buf = add_a_tok(strecpy(buf, ","), (args >> 16) & 0xF);
663 }
664 }
665 }
666 }
667
668 if (args & ATO) {
669 char tmp[256];
670 if (args & ATOWITHLASTPAREN) {
671 buf = strecpy(buf, ")");
672 }
673 strcpy(tmp, buforg);
674 emit_if(buforg, tmp);
675 } else {
676 if (!(args & ANOLASTPAREN)) {
677 buf = strecpy(buf, ")");
678 }
679 if (!(args & ANOENDSEMICOLON) && buf[(strlen(buf) - 1)] != ';') {
680 buf = strecpy(buf, ";");
681 }
682 }
683
684 return strchr(buf, 0);
685}
686
687void do_decodeparsestring_v2(char *buf, byte opcode) {
688 byte c;
689 bool flag;
690
691 while ((c = get_byte())) {
692 flag = (c & 0x80) != 0;
693 c &= 0x7f;
694
695 if (c < 8) {
696 buf += sprintf(buf, "\\x%.2X", (int)c);
697 if (c > 3) {
698 buf += sprintf(buf, "\\x%.2X", (int)get_byte());
699 }
700 } else {
701 if (c == '\\' || c == '"') // backslash is the escape character
702 *buf++ = '\\';
703 }
704 *buf++ = c;
705 if (flag)
706 *buf++ = ' ';
707 }
708 *buf = 0;
709}
710
711void do_actorops_v12(char *buf, byte opcode) {
712 buf = strecpy(buf, "ActorOps(");
713 buf = get_var_or_byte(buf, opcode & 0x80);
714 buf = strecpy(buf, ",[");
715
716 char arg[256];
717 get_var_or_byte(arg, opcode & 0x40);
718
719 int subop = get_byte();
720 switch(subop) {
721 case 1:
722 buf += sprintf(buf, "Sound(%s)", arg);
723 break;
724 case 2:
725 if (g_options.scriptVersion == 1)
726 buf += sprintf(buf, "Color(%s)", arg);
727 else
728 buf += sprintf(buf, "Color(%d, %s)", get_byte(), arg);
729 break;
730 case 3:
731 buf = do_tok(buf, "Name", A1ASCII | ANOENDSEMICOLON);
732 break;
733 case 4:
734 buf += sprintf(buf, "Costume(%s)", arg);
735 break;
736 case 5:
737 buf += sprintf(buf, "TalkColor(%s)", arg);
738 break;
739 default:
740 error("do_actorops_v12: unknown subop %d", subop);
741 }
742 strecpy(buf, "]);");
743}
744
745void do_actorops(char *buf, byte opcode) {
746 static const byte convertTable[20] =
747 { 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20 };
748
749 char first = 1;
750
751 buf = do_tok(buf, "ActorOps", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
752
753 buf = strecpy(buf, ",[");
754
755 do {
756 opcode = get_byte();
757 if (opcode == 0xFF)
758 break;
759 if (!first)
760 buf = strecpy(buf, ",");
761 first = 0;
762
763 // FIXME - this really should be a check for GF_SMALL_HEADER instead!
764 if (g_options.scriptVersion < 5)
765 opcode = (opcode & 0xE0) | convertTable[(opcode & 0x1F) - 1];
766
767 switch (opcode & 0x1F) {
768 case 0x00:
769 buf = do_tok(buf, "Unknown", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
770 break;
771 case 0x01:
772 buf = do_tok(buf, "Costume", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
773 break;
774 case 0x02:
775 buf = do_tok(buf, "WalkSpeed", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
776 break;
777 case 0x03:
778 buf = do_tok(buf, "Sound", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
779 break;
780 case 0x04:
781 buf = do_tok(buf, "WalkAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
782 break;
783 case 0x05:
784 buf =
785 do_tok(buf, "TalkAnimNr", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
786 break;
787 case 0x06:
788 buf = do_tok(buf, "StandAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
789 break;
790 case 0x07:
791 buf =
792 do_tok(buf, "Nothing",
793 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
794 ((opcode & 0x20) ? A3V : A3B) | ANOENDSEMICOLON);
795 break;
796 case 0x08:
797 buf = do_tok(buf, "Init", ANOENDSEMICOLON);
798 break;
799 case 0x09:
800 buf = do_tok(buf, "Elevation", ((opcode & 0x80) ? A1V : A1W) | ANOENDSEMICOLON);
801 break;
802 case 0x0A:
803 buf = do_tok(buf, "DefaultAnims", ANOENDSEMICOLON);
804 break;
805 case 0x0B:
806 buf = do_tok(buf, "Palette", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
807 break;
808 case 0x0C:
809 buf = do_tok(buf, "TalkColor", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
810 break;
811 case 0x0D:
812 buf = do_tok(buf, "Name", A1ASCII | ANOENDSEMICOLON);
813 break;
814 case 0x0E:
815 buf = do_tok(buf, "InitAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
816 break;
817// case 0x0F: buf=do_tok(buf, "PaletteList", A1LIST); break;
818 case 0x10:
819 buf = do_tok(buf, "Width", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
820 break;
821 case 0x11:
822 if (g_options.scriptVersion == 5)
823 buf = do_tok(buf, "Scale", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
824 else
825 buf = do_tok(buf, "Scale", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
826 break;
827 case 0x12:
828 buf = do_tok(buf, "NeverZClip", ANOENDSEMICOLON);
829 break;
830 case 0x13:
831 buf = do_tok(buf, "SetZClip", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
832 break;
833 case 0x14:
834 buf = do_tok(buf, "IgnoreBoxes", ANOENDSEMICOLON);
835 break;
836 case 0x15:
837 buf = do_tok(buf, "FollowBoxes", ANOENDSEMICOLON);
838 break;
839 case 0x16:
840 buf = do_tok(buf, "AnimSpeed", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
841 break;
842 case 0x17:
843 buf=do_tok(buf, "ShadowMode", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
844 break;
845 default:
846 buf += sprintf(buf, "Unknown%.2X()", opcode);
847 }
848 } while (1);
849
850 strecpy(buf, "]);");
851
852}
853
854static int g_numInExprStack;
855static char *g_exprStack[256];
856
857void pushExprStack(char *s) {
858 assert(g_numInExprStack < 256);
859 g_exprStack[g_numInExprStack++] = strdup(s);
860}
861
862char *popExprStack(char *buf) {
863 char *s;
864
865 if (g_numInExprStack <= 0) {
866 printf("Expression stack is empty!\n");
867 exit(0);
868 }
869
870 s = g_exprStack[--g_numInExprStack];
871 buf = strecpy(buf, s);
872 free(s);
873 return buf;
874}
875
876
877void do_expr_code(char *buf) {
878 int i;
879 const char *s;
880 char *buf2;
881
882 char tmp[256];
883
884 buf = strecpy(buf, "Exprmode ");
885 buf = get_var(buf);
886 buf = strecpy(buf, " = ");
887
888 g_numInExprStack = 0;
889
890 do {
891 i = get_byte();
892 if (i == 0xFF)
893 break;
894 switch (i & 0x1F) {
895 case 0x1:
896 get_var_or_word(buf, i & 0x80);
897 pushExprStack(buf);
898 break;
899
900 case 0x2:
901 s = " + ";
902 goto do_oper;
903
904 case 0x3:
905 s = " - ";
906 goto do_oper;
907
908 case 0x4:
909 s = " * ";
910 goto do_oper;
911
912 case 0x5:
913 s = " / ";
914 do_oper:;
915 buf2 = strecpy(buf, "(");
916 popExprStack(tmp);
917 buf2 = popExprStack(buf2);
918 buf2 = strecpy(buf2, s);
919 buf2 = strecpy(buf2, tmp);
920 strecpy(buf2, ")");
921 pushExprStack(buf);
922 break;
923
924 case 0x6:
925 buf2 = strecpy(buf, "<");
926 if (g_options.scriptVersion <= 2)
927 next_line_V12(buf2);
928 else
929 next_line_V345(buf2);
930 if (buf2[(strlen(buf2) - 1)] == ';') {
931 buf2[(strlen(buf2) - 1)] = 0;
932 }
933 strecpy(strchr(buf2, 0), ">");
934 pushExprStack(buf);
935 break;
936
937 default:
938 printf("Warning, Invalid expression code %.2X\n", i);
939 }
940
941 } while (1);
942
943 strcpy(popExprStack(buf), ";");
944}
945
946
947void do_load_code_to_string(char *buf, byte opcode) {
948
949 buf = strchr(strcpy(buf, "PutCodeInString("), 0);
950 buf = get_var_or_byte(buf, opcode & 0x80);
951 buf = strchr(strcpy(buf, ", "), 0);
952 buf = get_ascii(buf);
953 strcpy(buf, ");");
954}
955
956void do_resource_v2(char *buf, byte opcode) {
957 const char *resTypes[] = {
958 "UnkResType0",
959 "UnkResType1",
960 "Costume",
961 "Room",
962 "UnkResType4",
963 "Script",
964 "Sound"
965 };
966 char resid[256];
967 int subop;
968
969 get_var_or_byte(resid, opcode & 0x80);
970 subop = get_byte();
971
972 int type = subop >> 4;
973
974 if (((subop & 0x0F) == 0) || ((subop & 0x0F) == 1)) {
975 if (subop & 1)
976 buf += sprintf(buf, "load");
977 else
978 buf += sprintf(buf, "nuke");
979 assert(0 <= type && type < ARRAYSIZE(resTypes));
980 buf += sprintf(buf, resTypes[type]);
981 buf += sprintf(buf, "(%s)", resid);
982 } else {
983 if (subop & 1)
984 buf += sprintf(buf, "lock");
985 else
986 buf += sprintf(buf, "unlock");
987 assert(0 <= type && type < ARRAYSIZE(resTypes));
988 buf += sprintf(buf, resTypes[type]);
989 buf += sprintf(buf, "(%s)", resid);
990 }
991}
992
993void do_resource(char *buf, byte opco) {
994 char opcode = get_byte();
995 int subop;
996 if (g_options.scriptVersion != 5)
997 subop = opcode & 0x3F; // FIXME - actually this should only be done for Zak256
998 else
999 subop = opcode & 0x1F;
1000
1001 buf += sprintf(buf, "Resource.");
1002
1003 switch (subop) {
1004 case 0x1:
1005 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
1006 break;
1007 case 0x2:
1008 do_tok(buf, "loadSound", ((opcode & 0x80) ? A1V : A1B));
1009 break;
1010 case 0x3:
1011 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
1012 break;
1013 case 0x4:
1014 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
1015 break;
1016 case 0x5:
1017 do_tok(buf, "nukeScript", ((opcode & 0x80) ? A1V : A1B));
1018 break;
1019 case 0x6:
1020 do_tok(buf, "nukeSound", ((opcode & 0x80) ? A1V : A1B));
1021 break;
1022 case 0x7:
1023 do_tok(buf, "nukeCostume", ((opcode & 0x80) ? A1V : A1B));
1024 break;
1025 case 0x8:
1026 do_tok(buf, "nukeRoom", ((opcode & 0x80) ? A1V : A1B));
1027 break;
1028 case 0x9:
1029 do_tok(buf, "lockScript", ((opcode & 0x80) ? A1V : A1B));
1030 break;
1031 case 0xA:
1032 do_tok(buf, "lockSound", ((opcode & 0x80) ? A1V : A1B));
1033 break;
1034 case 0xB:
1035 do_tok(buf, "lockCostume", ((opcode & 0x80) ? A1V : A1B));
1036 break;
1037 case 0xC:
1038 do_tok(buf, "lockRoom", ((opcode & 0x80) ? A1V : A1B));
1039 break;
1040 case 0xD:
1041 do_tok(buf, "unlockScript", ((opcode & 0x80) ? A1V : A1B));
1042 break;
1043 case 0xE:
1044 do_tok(buf, "unlockSound", ((opcode & 0x80) ? A1V : A1B));
1045 break;
1046 case 0xF:
1047 do_tok(buf, "unlockCostume", ((opcode & 0x80) ? A1V : A1B));
1048 break;
1049 case 0x10:
1050 do_tok(buf, "unlockRoom", ((opcode & 0x80) ? A1V : A1B));
1051 break;
1052 case 0x11:
1053 do_tok(buf, "clearHeap", 0);
1054 break;
1055 case 0x12:
1056 do_tok(buf, "loadCharset", ((opcode & 0x80) ? A1V : A1B));
1057 break;
1058 case 0x13:
1059 do_tok(buf, "nukeCharset", ((opcode & 0x80) ? A1V : A1B));
1060 break;
1061 case 0x14:
1062 do_tok(buf, "loadFlObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
1063 break;
1064
1065 case 0x22 + 1:
1066 do_tok(buf, "setCDVolume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1067 break;
1068 case 0x23 + 1:
1069 do_tok(buf, "setSoundLoudness", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
1070 break;
1071 case 0x24 + 1:
1072 do_tok(buf, "setSoundPitch", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1073 break;
1074
1075
1076 default:
1077 error("do_resource: unhandled subop %d\n", subop);
1078 break;
1079 }
1080
1081}
1082
1083void do_pseudoRoom(char *buf) {
1084 int j, i = get_byte();
1085
1086 buf += sprintf(buf, "PseudoRoom(%d", i);
1087
1088 do {
1089 j = get_byte();
1090 if (!j)
1091 break;
1092
1093 if (j & 128)
1094 buf += sprintf(buf, ",%d", j & 127);
1095 else
1096 buf = strecpy(buf, ",IG");
1097 } while (1);
1098
1099 strcpy(buf, ");");
1100}
1101
1102void do_room_ops(char *buf) {
1103 int opcode = get_byte();
1104
1105 //buf+=sprintf(buf, "SubCode33%.2X", opcode);
1106
1107 switch (opcode & 0x1F) {
1108 case 0x01:
1109 do_tok(buf, "RoomScroll", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1110 break;
1111 case 0x02:
1112 do_tok(buf, "RoomColor", 0);
1113 break;
1114 case 0x03:
1115 do_tok(buf, "SetScreen", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1116 break;
1117 case 0x04:
1118 buf =
1119 do_tok(buf, "SetPalColor",
1120 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) |
1121 ((opcode & 0x20) ? A3V : A3W) | ANOLASTPAREN | ANOENDSEMICOLON);
1122 opcode = get_byte();
1123 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1124 break;
1125 case 0x05:
1126 do_tok(buf, "ShakeOn", 0);
1127 break;
1128 case 0x06:
1129 do_tok(buf, "ShakeOff", 0);
1130 break;
1131 case 0x07:
1132 // Possibly unused, but changed to match ScummVM anyway
1133 //do_tok(buf, "Unused", 0);
1134 buf = do_tok(buf, "SetRoomScale",
1135 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1136 ANOLASTPAREN | ANOENDSEMICOLON);
1137 opcode = get_byte();
1138 buf = do_tok(buf, NULL,
1139 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1140 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON);
1141 opcode = get_byte();
1142 buf = do_tok(buf, NULL,
1143 ((opcode & 0x40) ? A2V : A2B) | // apparently it uses the param 2 bit
1144 ASTARTCOMMA | ANOFIRSTPAREN);
1145 break;
1146 case 0x08:
1147 buf =
1148 do_tok(buf, "RoomIntensity",
1149 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1150 ((opcode & 0x20) ? A3V : A3B));
1151 break;
1152 case 0x09:
1153 buf = do_tok(buf, "saveLoad", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1154 break;
1155 case 0x0A:
1156 buf = do_tok(buf, "screenEffect", ((opcode & 0x80) ? A1V : A1W));
1157 break;
1158 case 0x0B:
1159 buf =
1160 do_tok(buf, "setRGBRoomIntensity",
1161 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1162 A2V : A2W) |
1163 ((opcode & 0x20) ? A3V : A3W));
1164 opcode = get_byte();
1165 buf =
1166 do_tok(buf, NULL,
1167 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1168 ((opcode & 0x40) ? A2V : A2B));
1169 break;
1170
1171 case 0x0C:
1172 buf =
1173 do_tok(buf, "setRoomShadow",
1174 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1175 A2V : A2W) |
1176 ((opcode & 0x20) ? A3V : A3W));
1177 opcode = get_byte();
1178 buf =
1179 do_tok(buf, NULL,
1180 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1181 ((opcode & 0x40) ? A2V : A2B));
1182 break;
1183
1184 case 0x0D:
1185 do_tok(buf, "saveString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1186 break;
1187 case 0x0E:
1188 do_tok(buf, "loadString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1189 break;
1190
1191 case 0x0F:
1192 buf = do_tok(buf, "palManipulate", ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1B));
1193 opcode = get_byte();
1194 buf =
1195 do_tok(buf, NULL,
1196 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ?
1197 A1V : A1B) |
1198 ((opcode & 0x40) ? A2V : A2B));
1199 opcode = get_byte();
1200 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1201 break;
1202
1203 case 0x10:
1204 do_tok(buf, "colorCycleDelay", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1205 break;
1206
1207 default:
1208 strcpy(buf, "Unknown??");
1209 }
1210}
1211
1212void do_room_ops_old(char *buf, byte opcode) {
1213 char a[256];
1214 char b[256];
1215
1216 if (g_options.scriptVersion <= 2) {
1217 get_var_or_byte(a, (opcode & 0x80));
1218 get_var_or_byte(b, (opcode & 0x40));
1219 } else if (g_options.scriptVersion == 3) {
1220 get_var_or_word(a, (opcode & 0x80));
1221 get_var_or_word(b, (opcode & 0x40));
1222 }
1223
1224 opcode = get_byte();
1225 switch (opcode & 0x1F) {
1226 case 0x01:
1227 if (g_options.scriptVersion > 3) {
1228 get_var_or_word(a, (opcode & 0x80));
1229 get_var_or_word(b, (opcode & 0x40));
1230 }
1231 buf = strecpy(buf, "RoomScroll(");
1232 buf = strecpy(buf, a);
1233 buf = strecpy(buf, ",");
1234 buf = strecpy(buf, b);
1235 buf = strecpy(buf, ")");
1236 break;
1237 case 0x02:
1238 if (g_options.scriptVersion > 3) {
1239 get_var_or_word(a, (opcode & 0x80));
1240 get_var_or_word(b, (opcode & 0x40));
1241 }
1242 buf = strecpy(buf, "RoomColor(");
1243 buf = strecpy(buf, a);
1244 buf = strecpy(buf, ",");
1245 buf = strecpy(buf, b);
1246 buf = strecpy(buf, ")");
1247 break;
1248 case 0x03:
1249 if (g_options.scriptVersion > 3) {
1250 get_var_or_word(a, (opcode & 0x80));
1251 get_var_or_word(b, (opcode & 0x40));
1252 }
1253 buf = strecpy(buf, "SetScreen(");
1254 buf = strecpy(buf, a);
1255 buf = strecpy(buf, ",");
1256 buf = strecpy(buf, b);
1257 buf = strecpy(buf, ")");
1258 break;
1259 case 0x04:
1260 if (g_options.scriptVersion > 3) {
1261 get_var_or_word(a, (opcode & 0x80));
1262 get_var_or_word(b, (opcode & 0x40));
1263 }
1264 buf = strecpy(buf, "SetPalColor(");
1265 buf = strecpy(buf, a);
1266 buf = strecpy(buf, ",");
1267 buf = strecpy(buf, b);
1268 buf = strecpy(buf, ")");
1269 break;
1270 case 0x05:
1271 do_tok(buf, "ShakeOn", 0);
1272 break;
1273 case 0x06:
1274 do_tok(buf, "ShakeOff", 0);
1275 break;
1276 default:
1277 error("do_room_ops_old: unknown subop %d", opcode & 0x1F);
1278 }
1279}
1280
1281void do_cursor_command(char *buf) {
1282 int opcode = get_byte();
1283
1284 switch (opcode & 0x1f) {
1285 case 0x01:
1286 do_tok(buf, "CursorShow", 0);
1287 break;
1288 case 0x02:
1289 do_tok(buf, "CursorHide", 0);
1290 break;
1291 case 0x03:
1292 do_tok(buf, "UserputOn", 0);
1293 break;
1294 case 0x04:
1295 do_tok(buf, "UserputOff", 0);
1296 break;
1297 case 0x05:
1298 do_tok(buf, "CursorSoftOn", 0);
1299 break;
1300 case 0x06:
1301 do_tok(buf, "CursorSoftOff", 0);
1302 break;
1303 case 0x07:
1304 do_tok(buf, "UserputSoftOn", 0);
1305 break;
1306 case 0x08:
1307 do_tok(buf, "UserputSoftOff", 0);
1308 break;
1309
1310 case 0x0A:
1311 do_tok(buf, "SetCursorImg", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1312 break;
1313 case 0x0B:
1314 do_tok(buf, "SetCursorHotspot",
1315 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1316 ((opcode & 0x20) ? A3V : A3B));
1317 break;
1318 case 0x0C:
1319 do_tok(buf, "InitCursor", ((opcode & 0x80) ? A1V : A1B));
1320 break;
1321 case 0x0D:
1322 do_tok(buf, "InitCharset", ((opcode & 0x80) ? A1V : A1B));
1323 break;
1324
1325 case 0x0E:
1326 if (g_options.scriptVersion == 3)
1327 do_tok(buf, "LoadCharset", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1328 else
1329 do_tok(buf, "CursorCommand", A1LIST);
1330 break;
1331 default:
1332 sprintf(buf, "UnknownCursorCommand%.2X", opcode);
1333 }
1334}
1335
1336void do_verbops_v2(char *buf, byte opcode) {
1337 int subop = get_byte();
1338
1339 buf = do_tok(buf, "VerbOps", ANOLASTPAREN | ANOENDSEMICOLON);
1340 switch (subop) {
1341 case 0:
1342 buf = do_tok(buf, "Delete", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1343 break;
1344 case 0xFF:
1345 buf = do_tok(buf, "State", A1B | A2B | ANOENDSEMICOLON);
1346 break;
1347 default:
1348 buf += sprintf(buf, "New-%d", subop);
1349 buf = do_tok(buf, "", A1B | A2B | ((opcode & 0x80) ? A3V : A3B) | A4B | A5ASCII | ANOENDSEMICOLON);
1350 }
1351 strecpy(buf, ");");
1352}
1353
1354void do_verbops(char *buf, byte opcode) {
1355 char first = 1;
1356
1357 buf = do_tok(buf, "VerbOps", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1358 buf = strecpy(buf, ",[");
1359
1360 do {
1361 opcode = get_byte();
1362 if (opcode == 0xFF)
1363 break;
1364 if (!first)
1365 buf = strecpy(buf, ",");
1366 first = 0;
1367 switch (opcode & 0x1F) {
1368 case 0x1:
1369 buf = do_tok(buf, "Image", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1370 break;
1371 case 0x2:
1372 buf = do_tok(buf, "Text", A1ASCII | ANOENDSEMICOLON);
1373 break;
1374 case 0x3:
1375 buf = do_tok(buf, "Color", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1376 break;
1377 case 0x4:
1378 buf = do_tok(buf, "HiColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1379 break;
1380 case 0x5:
1381 buf = do_tok(buf, "SetXY", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1382 break;
1383 case 0x6:
1384 buf = do_tok(buf, "On", ANOENDSEMICOLON);
1385 break;
1386 case 0x7:
1387 buf = do_tok(buf, "Off", ANOENDSEMICOLON);
1388 break;
1389 case 0x8:
1390 buf = do_tok(buf, "Delete", ANOENDSEMICOLON);
1391 break;
1392 case 0x9:
1393 buf = do_tok(buf, "New", ANOENDSEMICOLON);
1394 break;
1395 case 0x10:
1396 buf = do_tok(buf, "DimColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1397 break;
1398 case 0x11:
1399 buf = do_tok(buf, "Dim", ANOENDSEMICOLON);
1400 break;
1401 case 0x12:
1402 buf = do_tok(buf, "Key", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1403 break;
1404 case 0x13:
1405 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1406 break;
1407 case 0x14:
1408 buf = do_tok(buf, "SetToString", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1409 break;
1410 case 0x16:
1411 buf =
1412 do_tok(buf, "SetToObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
1413 break;
1414 case 0x17:
1415 buf = do_tok(buf, "BackColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1416 break;
1417 default:
1418 buf += sprintf(buf, "Invalid%.2X()", opcode);
1419 }
1420
1421 } while (1);
1422 strecpy(buf, "]);");
1423}
1424
1425void do_print_ego(char *buf, byte opcode) {
1426 char first = 1;
1427
1428 if (opcode == 0xD8) {
1429 buf = strecpy(buf, "printEgo([");
1430 } else {
1431 buf = do_tok(buf, "print", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1432 buf = strecpy(buf, ",[");
1433 }
1434
1435 do {
1436 opcode = get_byte();
1437 if (opcode == 0xFF)
1438 break;
1439
1440 if (!first)
1441 buf = strecpy(buf, ",");
1442 first = 0;
1443
1444 switch (opcode & 0x1f) {
1445 case 0x0:
1446 buf = do_tok(buf, "Pos", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1447 break;
1448 case 0x1:
1449 buf = do_tok(buf, "Color", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
1450 break;
1451 case 0x2:
1452 buf = do_tok(buf, "Clipped", ((opcode & 0x80) ? A1V : A1W) | ANOENDSEMICOLON);
1453 break;
1454 case 0x3:
1455 buf = do_tok(buf, "RestoreBG", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1456 break;
1457 case 0x4:
1458 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1459 break;
1460 case 0x6:
1461 if (g_options.GF_UNBLOCKED)
1462 buf = do_tok(buf, "Height", ((opcode & 0x80) ? A1V: A1W) | ANOENDSEMICOLON);
1463 else
1464 buf = do_tok(buf, "Left", ANOENDSEMICOLON);
1465 break;
1466 case 0x7:
1467 buf = do_tok(buf, "Overhead", ANOENDSEMICOLON);
1468 break;
1469 case 0x8:
1470 buf = do_tok(buf, "PlayCDTrack", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1471 break;
1472 case 0xF:{
1473 buf = strecpy(buf, "Text(");
1474 buf = get_ascii(buf);
1475 buf = strecpy(buf, ")");
1476 }
1477 goto exit_proc;
1478 default:
1479 buf += sprintf(buf, "Unknown%.2X()", opcode);
1480 goto exit_proc;
1481 }
1482 } while (1);
1483
1484exit_proc:;
1485 buf = strecpy(buf, "]);");
1486
1487}
1488
1489void do_unconditional_jump(char *buf) {
1490 int offset = get_word();
1491 int cur = get_curoffs();
1492 int to = cur + offset;
1493
1494 if (offset == 0) {
1495 sprintf(buf, "/* goto %.4X; */", to);
1496 } else if (!g_options.dontOutputElse && maybeAddElse(cur, to)) {
1497 pendingElse = true;
1498 pendingElseTo = to;
1499 pendingElseOffs = cur;
1500 pendingElseOpcode = g_jump_opcode;
1501 pendingElseIndent = g_blockStack.size();
1502 buf[0] = 0;
1503 } else {
1504 if (!g_blockStack.empty() && !g_options.dontOutputWhile) {
1505 Block p = g_blockStack.top();
1506 if (p.isWhile && cur == (int)p.to)
1507 return; // A 'while' ends here.
1508 }
1509 sprintf(buf, "goto %.4X;", to);
1510 }
1511}
1512
1513void emit_if(char *buf, char *condition) {
1514 int offset = get_word();
1515 int cur = get_curoffs();
1516 int to = cur + offset;
1517
1518 if (!g_options.dontOutputElseif && pendingElse) {
1519 if (maybeAddElseIf(cur, pendingElseTo, to)) {
1520 pendingElse = false;
1521 haveElse = true;
1522 buf = strecpy(buf, "} else if (");
1523 buf = strecpy(buf, condition);
1524 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1525 return;
1526 }
1527 }
1528
1529 if (!g_options.dontOutputIfs && maybeAddIf(cur, to)) {
1530 if (!g_options.dontOutputWhile && g_blockStack.top().isWhile) {
1531 buf = strecpy(buf, "while (");
1532 } else
1533 buf = strecpy(buf, "if (");
1534 buf = strecpy(buf, condition);
1535 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1536 return;
1537 }
1538
1539// buf = strecpy(buf, negate ? "if (" : "unless (");
1540 buf = strecpy(buf, "unless (");
1541 buf = strecpy(buf, condition);
1542 sprintf(buf, ") goto %.4X;", to);
1543}
1544
1545void do_if_code(char *buf, byte opcode) {
1546 char var[256];
1547 char tmp[256], tmp2[256];
1548 int txt;
1549
1550 const char *cmp_texts[8] = {
1551 " >= ", " < ", " <= ", " > ", " == ", " != ", "!", "",
1552 };
1553
1554 var[0] = 0;
1555 if (opcode != 0x28 && opcode != 0xA8)
1556 get_var(var);
1557
1558 switch (opcode & 0x7F) {
1559 case 0x38:
1560 txt = 0;
1561 break; /* lessOrEqual */
1562 case 0x04:
1563 txt = 2;
1564 break; /* isGreaterEqual */
1565 case 0x08:
1566 txt = 5;
1567 break; /* isNotEqual */
1568 case 0x48:
1569 txt = 4;
1570 break; /* isEqual */
1571 case 0x78:
1572 txt = 1;
1573 break; /* isGreater */
1574 case 0x44:
1575 txt = 3;
1576 break; /* isLess */
1577 case 0x28:
1578 txt = opcode & 128 ? 7 : 6;
1579 break;
1580 default:
1581 /* Exit, this should never happen, only if my code is buggy */
1582 error("Unknown IF code %x", opcode);
1583 }
1584
1585 if (opcode == 0x28 || opcode == 0xA8) {
1586 get_var(tmp2);
1587 } else {
1588 if (g_options.scriptVersion == 0)
1589 get_var_or_byte(tmp2, opcode & 0x80);
1590 else
1591 get_var_or_word(tmp2, opcode & 0x80);
1592 }
1593
1594 sprintf(tmp, "%s%s%s", var, cmp_texts[txt], tmp2);
1595 emit_if(buf, tmp);
1596}
1597
1598void do_if_active_object(char *buf, byte opcode) {
1599 char tmp[256];
1600
1601 int obj = get_byte();
1602 sprintf(tmp, "activeObject2 == %d", obj);
1603
1604 emit_if(buf, tmp);
1605}
1606
1607void do_if_state_code(char *buf, byte opcode) {
1608 char var[256];
1609 char tmp[256], tmp2[256];
1610 byte neg;
1611 int state = 0;
1612
1613 var[0] = 0;
1614 if (g_options.scriptVersion == 0) {
1615 if (opcode & 0x40)
1616 sprintf(var, "activeObject");
1617 else
1618 sprintf(var, "%d", get_byte());
1619 } else {
1620 get_var_or_word(var, opcode & 0x80);
1621 }
1622
1623 if (g_options.scriptVersion > 2) {
1624 switch (opcode & 0x2F) {
1625 case 0x0f:
1626 neg = 0;
1627 break;
1628 case 0x2f:
1629 neg = 1;
1630 break;
1631 default:
1632 /* Exit, this should never happen, only if my code is buggy */
1633 error("Unknown IF code %x", opcode);
1634 }
1635
1636 get_var_or_byte(tmp2, opcode & 0x40);
1637 } else {
1638 if (g_options.scriptVersion == 0) {
1639 switch (opcode) {
1640 case 0x7f:
1641 case 0xbf:
1642 state = 2;
1643 neg = 1;
1644 break;
1645 case 0x9f:
1646 case 0xdf:
1647 state = 4;
1648 neg = 1;
1649 break;
1650 case 0xaf:
1651 case 0xef:
1652 state = 8;
1653 neg = 1;
1654 break;
1655 case 0x3f:
1656 case 0xff:
1657 state = 2;
1658 neg = 0;
1659 break;
1660 case 0x1f:
1661 case 0x5f:
1662 state = 4;
1663 neg = 0;
1664 break;
1665 case 0x2f:
1666 case 0x6f:
1667 state = 8;
1668 neg = 0;
1669 break;
1670 default:
1671 /* Exit, this should never happen, only if my code is buggy */
1672 error("Unknown IF code %x", opcode);
1673 }
1674 } else {
1675 switch (opcode) {
1676 case 0x3f:
1677 case 0xbf:
1678 state = 1;
1679 neg = 1;
1680 break;
1681 case 0x5f:
1682 case 0xdf:
1683 state = 2;
1684 neg = 1;
1685 break;
1686 case 0x2f:
1687 case 0xaf:
1688 state = 4;
1689 neg = 1;
1690 break;
1691 case 0x0f:
1692 case 0x8f:
1693 state = 8;
1694 neg = 1;
1695 break;
1696 case 0x7f:
1697 case 0xff:
1698 state = 1;
1699 neg = 0;
1700 break;
1701 case 0x1f:
1702 case 0x9f:
1703 state = 2;
1704 neg = 0;
1705 break;
1706 case 0x6f:
1707 case 0xef:
1708 state = 4;
1709 neg = 0;
1710 break;
1711 case 0x4f:
1712 case 0xcf:
1713 state = 8;
1714 neg = 0;
1715 break;
1716 default:
1717 /* Exit, this should never happen, only if my code is buggy */
1718 error("Unknown IF code %x", opcode);
1719 }
1720 }
1721 }
1722
1723 if (g_options.scriptVersion > 2)
1724 sprintf(tmp, "getState(%s)%s%s", var, neg ? " != " : " == ", tmp2);
1725 else
1726 sprintf(tmp, "%sgetState%02d(%s)", neg ? "!" : "", state, var);
1727 emit_if(buf, tmp);
1728}
1729
1730void do_varset_code(char *buf, byte opcode) {
1731 const char *s;
1732
1733 if ((g_options.scriptVersion <= 2)
1734 && ((opcode & 0x7F) == 0x0A
1735 || (opcode & 0x7F) == 0x2A
1736 || (opcode & 0x7F) == 0x6A)) {
1737
1738 int i = get_byte();
1739 buf += sprintf(buf, "Var[Var[%d]]", i);
1740 } else
1741 buf = get_var(buf);
1742
1743 switch (opcode & 0x7F) {
1744 case 0x0A:
1745 case 0x1A:
1746 case 0x2C:
1747 s = " = ";
1748 break; /* move */
1749 case 0x1B:
1750 s = " *= ";
1751 break; /* mul */
1752 case 0x3A:
1753 case 0x6A:
1754 s = " -= ";
1755 break; /* sub */
1756 case 0x57:
1757 s = " |= ";
1758 break; /* or */
1759 case 0x2A:
1760 case 0x5A:
1761 s = " += ";
1762 break; /* add */
1763 case 0x5B:
1764 s = " /= ";
1765 break; /* divide */
1766 case 0x17:
1767 s = " &= ";
1768 break; /* and */
1769 case 0x46:
1770 if (opcode & 128)
1771 s = "--";
1772 else
1773 s = "++";
1774 break; /* increment & decrement */
1775 default:
1776 /* Exit, this should never happen, only if my code is buggy */
1777 error("Unknown VARSET code %x", opcode);
1778 }
1779
1780 buf = strecpy(buf, s);
1781
1782
1783 if ((g_options.scriptVersion <= 2) && (opcode & 0x7F) == 0x2C) { /* assignVarByte */
1784 sprintf(buf, "%d", get_byte());
1785 buf = strchr(buf, 0);
1786 } else if ((opcode & 0x7F) != 0x46) { /* increment or decrement */
1787 if (g_options.scriptVersion == 0)
1788 buf = get_var_or_byte(buf, opcode & 0x80);
1789 else
1790 buf = get_var_or_word(buf, opcode & 0x80);
1791 }
1792 strecpy(buf, ";");
1793}
1794
1795void do_matrix_ops(char *buf, byte opcode) {
1796 opcode = get_byte();
1797
1798 switch (opcode & 0x1F) {
1799 case 0x1:
1800 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1801 break;
1802 case 0x2:
1803 do_tok(buf, "setBoxScale", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1804 break;
1805 case 0x3:
1806 do_tok(buf, "SetBoxSlot", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1807 break;
1808 case 0x4:
1809 do_tok(buf, "createBoxMatrix", 0);
1810 break;
1811 default:
1812 sprintf(buf, "SetBoxUnknown%.2X;", opcode);
1813 }
1814}
1815
1816void next_line_V12(char *buf) {
1817 byte opcode = get_byte();
1818
1819 switch (opcode) {
1820
1821 case 0x58:
1822 do_tok(buf, "beginOverride", 0);
1823 break;
1824 case 0x52:
1825 case 0xD2:
1826 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
1827 break;
1828 case 0x15:
1829 case 0x55:
1830 case 0x95:
1831 case 0xD5:
1832 do_tok(buf, "actorFromPos",
1833 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
1834 break;
1835 case 0x13:
1836 case 0x53:
1837 case 0x93:
1838 case 0xD3:
1839 // actorSet
1840 do_actorops_v12(buf, opcode);
1841 break;
1842
1843 case 0x2A:
1844 case 0xAA:
1845 // addDirect
1846 case 0x3A:
1847 case 0xBA:
1848 //subtract
1849 case 0x6A:
1850 case 0xEA:
1851 //subDirect
1852 case 0x0A:
1853 case 0x8A:
1854 // assignVarWordDirect
1855 case 0x1A:
1856 case 0x5A:
1857 case 0x9A:
1858 case 0xDA:
1859 do_varset_code(buf, opcode);
1860 break;
1861
1862 case 0x11:
1863 case 0x51:
1864 case 0x91:
1865 case 0xD1:
1866 // animateActor
1867 do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1868 break;
1869 case 0x2C:
1870 // assignVarByte
1871 do_varset_code(buf, opcode);
1872 break;
1873 case 0x80:
1874 do_tok(buf, "breakHere", 0);
1875 break;
1876 case 0x4A:
1877 case 0xCA:
1878 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B));
1879 break;
1880
1881 case 0x60:
1882 case 0xE0:
1883 //do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1W));
1884 if (opcode & 0x80) {
1885 char tmp[256];
1886 get_var(tmp);
1887 buf += sprintf(buf, "cursorCommand(Hi(%s), Lo(%s));", tmp, tmp);
1888 } else {
1889 int val = get_word();
1890 buf += sprintf(buf, "cursorCommand(%d, %d);", (val >> 8) & 0xFF, val & 0xFF);
1891 }
1892
1893 break;
1894 case 0x40:
1895 sprintf(buf, "cutscene();");
1896 break;
1897 case 0xC0:
1898 sprintf(buf, "endCutscene();");
1899 break;
1900
1901 case 0x46:
1902 case 0xC6:
1903 // increment / decrement
1904 do_varset_code(buf, opcode);
1905 break;
1906
1907 case 0x2E: {
1908 //delay
1909 int d = get_byte();
1910 d |= get_byte() << 8;
1911 d |= get_byte() << 16;
1912 d = 0xFFFFFF - d;
1913 sprintf(buf, "delay(%d);", d);
1914 break;
1915 }
1916
1917 case 0x2B:
1918 do_tok(buf, "delayVariable", A1V);
1919 break;
1920
1921 case 0x19:
1922 case 0x39:
1923 case 0x59:
1924 case 0x79:
1925 case 0x99:
1926 case 0xB9:
1927 case 0xD9:
1928 case 0xF9:{
1929 buf = strecpy(buf, "doSentence(");
1930 if (!(opcode & 0x80) && *g_scriptCurPos == 0xFC) {
1931 strcpy(buf, "STOP)");
1932 g_scriptCurPos++;
1933 } else if (!(opcode & 0x80) && *g_scriptCurPos == 0xFB) {
1934 strcpy(buf, "RESET)");
1935 g_scriptCurPos++;
1936 } else {
1937 do_tok(buf, "",
1938 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1939 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W) | A4B);
1940 }
1941 }
1942 break;
1943
1944 case 0x05:
1945 case 0x25:
1946 case 0x45:
1947 case 0x65:
1948 case 0x85:
1949 case 0xA5:
1950 case 0xC5:
1951 case 0xE5:
1952 //drawObject
1953 buf = do_tok(buf, "drawObject",
1954 ((opcode & 0x80) ? A1V : A1W) |
1955 ((opcode & 0x40) ? A2V : A2B) |
1956 ((opcode & 0x20) ? A3V : A3B));
1957 break;
1958 case 0xAC:
1959 //drawSentence
1960 do_tok(buf, "drawSentence", 0);
1961 break;
1962 case 0x5C:
1963 case 0x6B:
1964 case 0x6E:
1965 case 0xAB:
1966 case 0xDC:
1967 case 0xEB:
1968 case 0xEE:
1969 //dummy
1970 sprintf(buf, "dummy(%.2X);", opcode);
1971
1972 break;
1973
1974 case 0x09:
1975 case 0x49:
1976 case 0x89:
1977 case 0xC9:
1978 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1979 break;
1980 case 0x35:
1981 case 0x75:
1982 case 0xB5:
1983 case 0xF5:
1984 do_tok(buf, "findObject",
1985 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1986 break;
1987 case 0x71:
1988 case 0xF1:
1989 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1990 break;
1991 case 0x06:
1992 case 0x86:
1993 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1994 break;
1995 case 0x63:
1996 case 0xE3:
1997 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1998 break;
1999 case 0x56:
2000 case 0xD6:
2001 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2002 break;
2003 case 0x03:
2004 case 0x83:
2005 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2006 break;
2007 case 0x7B:
2008 case 0xFB:
2009 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2010 break;
2011 case 0x43:
2012 case 0xC3:
2013 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2014 break;
2015
2016 case 0x23:
2017 case 0xA3:
2018 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2019 break;
2020
2021 case 0x31:
2022 case 0xB1:
2023 do_tok(buf, "getBitVar", AVARSTORE | A1W | ((opcode & 0x80) ? A2V : A2B));
2024 break;
2025
2026 case 0x1B:
2027 case 0x5B:
2028 case 0x9B:
2029 case 0xDB:
2030 do_tok(buf, "setBitVar", A1W | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2031 break;
2032
2033 case 0x66:
2034 case 0xE6:
2035 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2036 break;
2037
2038 case 0x34:
2039 case 0x74:
2040 case 0xB4:
2041 case 0xF4:
2042 do_tok(buf, "getDist",
2043 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
2044 break;
2045 case 0x10:
2046 case 0x90:
2047 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2048 break;
2049 case 0x6C:
2050 case 0xEC:
2051 do_tok(buf, "getObjPreposition", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2052 break;
2053 case 0x16:
2054 case 0x96:
2055 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2056 break;
2057
2058 case 0x1D:
2059 case 0x5D:
2060 case 0x9D:
2061 case 0xDD:
2062 //ifClassOfIs
2063 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ATO | ATOWITHLASTPAREN);
2064 break;
2065
2066 case 0x3F:
2067 case 0xBF:
2068 //ifNotState01
2069 case 0x5F:
2070 case 0xDF:
2071 //ifNotState02
2072 case 0x2F:
2073 case 0xAF:
2074 //ifNotState04
2075 case 0x0F:
2076 case 0x8F:
2077 //ifNotState08
2078 case 0x7F:
2079 case 0xFF:
2080 //ifState01
2081 case 0x1F:
2082 case 0x9F:
2083 //ifState02
2084 case 0x6F:
2085 case 0xEF:
2086 //ifState04
2087 case 0x4F:
2088 case 0xCF:
2089 //ifState08
2090 do_if_state_code(buf, opcode);
2091 break;
2092
2093 case 0x48:
2094 case 0xC8:
2095 //isEqual
2096 case 0x78:
2097 case 0xF8:
2098 //isGreater
2099 case 0x04:
2100 case 0x84:
2101 //isGreaterEqual
2102 case 0x44:
2103 case 0xC4:
2104 //isLess
2105 case 0x08:
2106 case 0x88:
2107 //isNotEqual
2108 case 0x38:
2109 case 0xB8:
2110 //lessOrEqual
2111 case 0x28:
2112 //equalZero
2113 case 0xA8:
2114 //notEqualZero
2115 do_if_code(buf, opcode);
2116 break;
2117
2118 case 0x68:
2119 case 0xE8:
2120 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2121 break;
2122 case 0x7C:
2123 case 0xFC:
2124 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2125 break;
2126
2127 case 0x18:
2128 do_unconditional_jump(buf);
2129 break;
2130
2131 case 0x70:
2132 case 0xF0:
2133 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
2134 break;
2135 case 0x72:
2136 case 0xF2:
2137 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2138 break;
2139
2140 case 0x24:
2141 case 0x64:
2142 case 0xA4:
2143 case 0xE4:
2144 //loadRoomWithEgo
2145 buf =
2146 do_tok(buf, "loadRoomWithEgo",
2147 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
2148 do_tok(buf, NULL, A1B | A2B | ANOFIRSTPAREN | ASTARTCOMMA);
2149 break;
2150
2151 case 0x30:
2152 case 0xB0:
2153 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
2154 break;
2155
2156 case 0x12:
2157 case 0x92:
2158 //panCameraTo
2159 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2160 break;
2161 case 0x50:
2162 case 0xD0:
2163 //pickupObject
2164 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
2165 break;
2166 case 0x14:
2167 case 0x94:
2168 // print
2169 buf += sprintf(buf, "print(");
2170 buf = get_var_or_byte(buf, (opcode & 0x80));
2171 buf += sprintf(buf, ",\"");
2172 do_decodeparsestring_v2(buf, opcode);
2173 strcat(buf, "\");");
2174 break;
2175 case 0xD8:
2176 //printEgo
2177 buf += sprintf(buf, "printEgo(\"");
2178 do_decodeparsestring_v2(buf, opcode);
2179 strcat(buf, "\");");
2180 break;
2181
2182 case 0xCC:
2183 // pseudoRoom
2184 do_pseudoRoom(buf);
2185 break;
2186 case 0x01:
2187 case 0x21:
2188 case 0x41:
2189 case 0x61:
2190 case 0x81:
2191 case 0xA1:
2192 case 0xC1:
2193 case 0xE1:
2194 do_tok(buf, "putActor",
2195 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2196 ((opcode & 0x20) ? A3V : A3B));
2197 break;
2198 case 0x0E:
2199 case 0x4E:
2200 case 0x8E:
2201 case 0xCE:
2202 //putActorAtObject
2203 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) );
2204 break;
2205 case 0x2D:
2206 case 0x6D:
2207 case 0xAD:
2208 case 0xED:
2209 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2210 break;
2211 case 0x0C:
2212 case 0x8C:
2213 //resourceRoutines
2214 do_resource_v2(buf, opcode);
2215 break;
2216 case 0x98:
2217 do_tok(buf, "restart", 0);
2218 break;
2219
2220 case 0x33:
2221 case 0x73:
2222 case 0xB3:
2223 case 0xF3:
2224 do_room_ops_old(buf, opcode);
2225 break;
2226
2227 case 0x22:
2228 case 0xA2:
2229 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2230 break;
2231
2232 case 0x3D:
2233 case 0x7D:
2234 case 0xBD:
2235 case 0xFD:
2236 do_tok(buf, "setActorElevation", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2237 break;
2238
2239 case 0x32:
2240 case 0xB2:
2241 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2242 break;
2243
2244 case 0x54:
2245 case 0xD4:
2246 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
2247 break;
2248
2249 case 0x0B:
2250 case 0x4B:
2251 case 0x8B:
2252 case 0xCB:
2253 do_tok(buf, "setObjPreposition", ((opcode & 0x80) ? A1V : A1W) | A2B);
2254 break;
2255 case 0x29:
2256 case 0x69:
2257 case 0xA9:
2258 case 0xE9:
2259 //setOwnerOf
2260 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
2261 break;
2262
2263 case 0x77:
2264 case 0xF7:
2265 // clearState01
2266 do_tok(buf, "clearState01", ((opcode & 0x80) ? A1V : A1W));
2267 break;
2268 case 0x17:
2269 case 0x97:
2270 // clearState02
2271 do_tok(buf, "clearState02", ((opcode & 0x80) ? A1V : A1W));
2272 break;
2273 case 0x67:
2274 case 0xE7:
2275 // clearState04
2276 do_tok(buf, "clearState04", ((opcode & 0x80) ? A1V : A1W));
2277 break;
2278 case 0x47:
2279 case 0xC7:
2280 // clearState08
2281 do_tok(buf, "clearState08", ((opcode & 0x80) ? A1V : A1W));
2282 break;
2283
2284 case 0x37:
2285 case 0xB7:
2286 //setState01
2287 do_tok(buf, "setState01", ((opcode & 0x80) ? A1V : A1W));
2288 break;
2289 case 0x57:
2290 case 0xD7:
2291 //setState02
2292 do_tok(buf, "setState02", ((opcode & 0x80) ? A1V : A1W));
2293 break;
2294 case 0x27:
2295 case 0xA7:
2296 //setState04
2297 do_tok(buf, "setState04", ((opcode & 0x80) ? A1V : A1W));
2298 break;
2299 case 0x07:
2300 case 0x87:
2301 //setState08
2302 do_tok(buf, "setState08", ((opcode & 0x80) ? A1V : A1W));
2303 break;
2304
2305 case 0x26:
2306 case 0xA6: {
2307 int i;
2308 char first = 1;
2309
2310 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN);
2311 i = get_byte();
2312
2313 buf += sprintf(buf, ",%d,[", i);
2314
2315 while (i > 0) {
2316 if (!first)
2317 buf = strecpy(buf, ",");
2318 first = 0;
2319
2320 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
2321 i--;
2322 }
2323
2324 strcpy(buf, "]);");
2325
2326 }
2327 break;
2328
2329 case 0x02:
2330 case 0x82:
2331 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2332 break;
2333 case 0x42:
2334 case 0xC2:
2335 //startScript
2336 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2337 break;
2338
2339 case 0x1C:
2340 case 0x9C:
2341 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2342 break;
2343
2344 case 0x20:
2345 do_tok(buf, "stopMusic", 0);
2346 break;
2347 case 0x00:
2348 case 0xA0:
2349 do_tok(buf, "stopObjectCode", 0);
2350 break;
2351 case 0x62:
2352 case 0xE2:
2353 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2354 break;
2355
2356 case 0x3C:
2357 case 0xBC:
2358 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2359 break;
2360
2361 case 0x7A:
2362 case 0xFA:
2363 // verbOps
2364 do_verbops_v2(buf, opcode);
2365 break;
2366
2367 case 0x3B:
2368 case 0xBB:
2369 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
2370 break;
2371
2372 case 0x4C:
2373 do_tok(buf, "waitForSentence", 0);
2374 break;
2375
2376 case 0xAE:
2377 do_tok(buf, "waitForMessage", 0);
2378 break;
2379 case 0x1E:
2380 case 0x3E:
2381 case 0x5E:
2382 case 0x7E:
2383 case 0x9E:
2384 case 0xBE:
2385 case 0xDE:
2386 case 0xFE:
2387 do_tok(buf, "walkActorTo",
2388 ((opcode & 0x80) ? A1V : A1B) |
2389 ((opcode & 0x40) ? A2V : A2B) |
2390 ((opcode & 0x20) ? A3V : A3B));
2391 break;
2392
2393 case 0x0D:
2394 case 0x4D:
2395 case 0x8D:
2396 case 0xCD:
2397 do_tok(buf, "walkActorToActor",
2398 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2399 break;
2400 case 0x36:
2401 case 0x76:
2402 case 0xB6:
2403 case 0xF6:
2404 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
2405 break;
2406
2407 default:
2408 error("Unknown opcode %.2X", opcode);
2409 }
2410}
2411
2412void next_line_V0(char *buf) {
2413 byte opcode = get_byte();
2414
2415 switch (opcode) {
2416 case 0x05:
2417 case 0x09:
2418 case 0x0A:
2419 case 0x19:
2420 case 0x23:
2421 case 0x2C:
2422 case 0x35:
2423 case 0x39:
2424 case 0x3B:
2425 case 0x45:
2426 case 0x49:
2427 case 0x59:
2428 case 0x63:
2429 case 0x65:
2430 case 0x6A:
2431 case 0x6C:
2432 case 0x79:
2433 case 0x7A:
2434 case 0x7B:
2435 case 0x80:
2436 case 0x82:
2437 case 0x85:
2438 case 0x89:
2439 case 0x8A:
2440 case 0x8D:
2441 case 0x96:
2442 case 0x99:
2443 case 0xA3:
2444 case 0xA6:
2445 case 0xAA:
2446 case 0xAC:
2447 case 0xB5:
2448 case 0xB9:
2449 case 0xBB:
2450 case 0xC5:
2451 case 0xC9:
2452 case 0xD8:
2453 case 0xD9:
2454 case 0xE3:
2455 case 0xE6:
2456 case 0xEA:
2457 case 0xEC:
2458 case 0xF5:
2459 case 0xF9:
2460 case 0xFA:
2461 case 0xFB:
2462 do_tok(buf, "stopCurrentScript", 0);
2463 break;
2464
2465 case 0x67:
2466 case 0xE7:
2467 do_tok(buf, "getActorFacing", AVARSTORE | A1B | ((opcode & 0x80) ? A2V : A2B));
2468 break;
2469
2470 case 0x31:
2471 case 0x71:
2472 case 0xB1:
2473 case 0xF1:
2474 do_tok(buf, "getBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2475 break;
2476
2477 case 0x1D:
2478 case 0x3D:
2479 case 0x5D:
2480 case 0x7D:
2481 case 0x9D:
2482 case 0xBD:
2483 case 0xDD:
2484 case 0xFD:
2485 do_tok(buf, "setBitVar", A1B | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2486 break;
2487
2488 case 0x1B:
2489 case 0x5B:
2490 case 0x9B:
2491 case 0xDB:
2492 do_tok(buf, "getActorBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2493 break;
2494
2495 case 0x0B:
2496 case 0x2B:
2497 case 0x4B:
2498 case 0x6B:
2499 case 0x8B:
2500 case 0xAB:
2501 case 0xCB:
2502 case 0xEB:
2503 do_tok(buf, "setActorBitVar", A1B | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2504 break;
2505
2506 case 0x58:
2507 do_tok(buf, "beginOverride", 0);
2508 get_byte();
2509 get_byte();
2510 get_byte();
2511 break;
2512 case 0x52:
2513 case 0xD2:
2514 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
2515 break;
2516 case 0x95:
2517 case 0xD5:
2518 do_tok(buf, "actorFromPos",
2519 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
2520 break;
2521 case 0x15:
2522 case 0x55:
2523 do_tok(buf, "walkActorToActor",
2524 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2525 break; /* arg1=actor, arg2=actor */
2526 case 0x13:
2527 do_tok(buf, "lockCostume", A1B);
2528 break;
2529 case 0x4D:
2530 do_tok(buf, "lockRoom", A1B);
2531 break;
2532 case 0xCD:
2533 do_tok(buf, "unlockRoom", A1B);
2534 break;
2535 case 0x93:
2536 do_tok(buf, "unlockCostume", A1B);
2537 break;
2538 case 0x1A:
2539 case 0x9a:
2540 //move
2541 case 0x5A:
2542 case 0xDA:
2543 //add;
2544 case 0x3A:
2545 case 0xBA:
2546 //subtract
2547 do_varset_code(buf, opcode);
2548 break;
2549
2550 case 0x11:
2551 case 0x51:
2552 case 0x91:
2553 case 0xD1:
2554 buf = do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2555 break;
2556 case 0x10:
2557 do_tok(buf, "breakHere", 0);
2558 break;
2559 case 0x4A:
2560 case 0xCA:
2561 do_tok(buf, "loadRoom_c64", ((opcode & 0x80) ? A1V : A1B));
2562 break;
2563
2564 case 0x60:
2565 case 0xE0:
2566 //cursorCommand
2567 do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1B));
2568 break;
2569 case 0x40:
2570 do_tok(buf, "cutscene", 0);
2571 break;
2572 case 0xC0:
2573 do_tok(buf, "endCutscene", 0);
2574 break;
2575
2576 case 0x46:
2577 case 0xC6:
2578 // increment / decrement
2579 do_varset_code(buf, opcode);
2580 break;
2581
2582 case 0x2A: {
2583 //delay
2584 int d = get_byte();
2585 d |= get_byte() << 8;
2586 d |= get_byte() << 16;
2587 d = 0xFFFFFF - d;
2588 sprintf(buf, "delay(%d);", d);
2589 break;
2590 }
2591
2592 case 0x50:
2593 case 0x72:
2594 case 0xD0:
2595 case 0xF2:
2596 do_tok(buf, "nop", 0);
2597 break;
2598 case 0x14:
2599 case 0x94:
2600 // print
2601 buf += sprintf(buf, "print(");
2602 buf = get_var_or_byte(buf, (opcode & 0x80));
2603 buf += sprintf(buf, ",\"");
2604 do_decodeparsestring_v2(buf, opcode);
2605 strcat(buf, "\");");
2606 break;
2607 case 0x75:
2608 //printEgo
2609 buf += sprintf(buf, "printEgo(\"");
2610 do_decodeparsestring_v2(buf, opcode);
2611 strcat(buf, "\");");
2612 break;
2613 case 0x2E:
2614 case 0xAE:
2615 // print_c64
2616 buf += sprintf(buf, "print_c64(");
2617 buf = get_var_or_byte(buf, (opcode & 0x80));
2618 buf += sprintf(buf, ",\"");
2619 do_decodeparsestring_v2(buf, opcode);
2620 strcat(buf, "\");");
2621 break;
2622 case 0x0D:
2623 //printEgo_c64
2624 buf += sprintf(buf, "printEgo_c64(\"");
2625 do_decodeparsestring_v2(buf, opcode);
2626 strcat(buf, "\");");
2627 break;
2628
2629 case 0x2D:
2630 case 0x6D:
2631 case 0xAD:
2632 case 0xED:
2633 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2634 break;
2635 case 0xE5:
2636 do_tok(buf, "loadRoomWithEgo", A1B | A2B);
2637 break;
2638 case 0x6E:
2639 case 0xEE:
2640 //dummy
2641 sprintf(buf, "dummy%.2X();", opcode);
2642 break;
2643
2644 case 0x86:
2645 do_tok(buf, "bad", 0);
2646 break;
2647 case 0x56:
2648 case 0xD6:
2649 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2650 break;
2651 case 0x03:
2652 case 0x43:
2653 case 0x83:
2654 case 0xC3:
2655 do_tok(buf, "doSentence", A1B | A2B | A3B);
2656 break;
2657 case 0x07:
2658 case 0x87:
2659 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2660 break;
2661 case 0x47:
2662 case 0xC7:
2663 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2664 break;
2665
2666 case 0x27:
2667 case 0xA7:
2668 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2669 break;
2670
2671 case 0x26:
2672 do_tok(buf, "getClosestObjActor7", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2673 break;
2674 case 0x66:
2675 do_tok(buf, "getClosestObjActor25", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2676 break;
2677
2678 case 0x06:
2679 case 0x34:
2680 case 0x74:
2681 case 0xB4:
2682 case 0xF4:
2683 do_tok(buf, "getDist",
2684 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2685 break;
2686 case 0x90:
2687 do_tok(buf, "pickupObject", A1B);
2688 break;
2689 case 0x16:
2690 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2691 break;
2692
2693 case 0x0f:
2694 case 0x4f:
2695 do_tok(buf, "clearState02", ((opcode & 0x40) ? 0 : A1B));
2696 break;
2697 case 0x37:
2698 case 0x77:
2699 do_tok(buf, "clearState04", ((opcode & 0x40) ? 0 : A1B));
2700 break;
2701 case 0x17:
2702 case 0x57:
2703 do_tok(buf, "clearState08", ((opcode & 0x40) ? 0 : A1B));
2704 break;
2705 case 0x8f:
2706 case 0xcf:
2707 do_tok(buf, "setState02", ((opcode & 0x40) ? 0 : A1B));
2708 break;
2709 case 0xb7:
2710 case 0xf7:
2711 do_tok(buf, "setState04", ((opcode & 0x40) ? 0 : A1B));
2712 break;
2713 case 0x97:
2714 case 0xd7:
2715 do_tok(buf, "setState08", ((opcode & 0x40) ? 0 : A1B));
2716 break;
2717
2718 case 0x3f:
2719 case 0xff:
2720 //ifState02;
2721 case 0x1f:
2722 case 0x5f:
2723 //ifState04;
2724 case 0x2f:
2725 case 0x6f:
2726 //ifState08;
2727 case 0x7f:
2728 case 0xbf:
2729 //ifNotState02;
2730 case 0x9f:
2731 case 0xdf:
2732 //ifNotState04;
2733 case 0xaf:
2734 case 0xef:
2735 //ifNotState08;
2736 do_if_state_code(buf, opcode);
2737 break;
2738
2739 case 0x48:
2740 case 0xC8:
2741 //isEqual
2742 case 0x78:
2743 case 0xF8:
2744 //isGreater
2745 case 0x04:
2746 case 0x84:
2747 //isGreaterEqual
2748 case 0x44:
2749 case 0xC4:
2750 //isLess
2751 case 0x08:
2752 case 0x88:
2753 //isNotEqual
2754 case 0x38:
2755 case 0xB8:
2756 //lessOrEqual
2757 case 0x28:
2758 //equalZero
2759 case 0xA8:
2760 //notEqualZero
2761 do_if_code(buf, opcode);
2762 break;
2763
2764 case 0x68:
2765 case 0xE8:
2766 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2767 break;
2768 case 0x7C:
2769 case 0xFC:
2770 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2771 break;
2772
2773 case 0x53:
2774 do_tok(buf, "lockSound", A1B);
2775 break;
2776
2777 case 0xD3:
2778 do_tok(buf, "unlockSound", A1B);
2779 break;
2780
2781 case 0x18:
2782 do_unconditional_jump(buf);
2783 break;
2784
2785 case 0x70:
2786 case 0xF0:
2787 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B));
2788 break;
2789 case 0x25:
2790 case 0xA5:
2791 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2792 break;
2793
2794 case 0x24:
2795 case 0xA4:
2796 do_tok(buf, "unknown2", A1B);
2797 break;
2798 case 0x64:
2799 case 0xE4:
2800 do_if_active_object(buf, opcode);
2801 break;
2802
2803 case 0x30:
2804 case 0xB0:
2805 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
2806 break;
2807
2808 case 0x12:
2809 case 0x92:
2810 //panCameraTo
2811 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2812 break;
2813
2814 case 0x01:
2815 case 0x21:
2816 case 0x41:
2817 case 0x61:
2818 case 0x81:
2819 case 0xA1:
2820 case 0xC1:
2821 case 0xE1:
2822 do_tok(buf, "putActor",
2823 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2824 ((opcode & 0x20) ? A3V : A3B));
2825 break;
2826 case 0x4E:
2827 case 0xCE:
2828 case 0x0E:
2829 case 0x8E:
2830 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | A2B);
2831 break;
2832 case 0x0C:
2833 case 0x8C:
2834 do_tok(buf, "loadSound", A1B);
2835 break;
2836 case 0x98:
2837 do_tok(buf, "restart", 0);
2838 break;
2839
2840 case 0x33:
2841 do_tok(buf, "lockScript", A1B);
2842 break;
2843 case 0xB3:
2844 do_tok(buf, "unlockScript", A1B);
2845 break;
2846 case 0x73:
2847 case 0xF3:
2848 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2849 break;
2850
2851 case 0x22:
2852 case 0xA2:
2853 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2854 break;
2855
2856 case 0x32:
2857 case 0xB2:
2858 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2859 break;
2860
2861 case 0x54:
2862 case 0xD4:
2863 do_tok(buf, "setObjectName", A1B | A2ASCII);
2864 break;
2865
2866 case 0x29:
2867 case 0x69:
2868 case 0xA9:
2869 case 0xE9:
2870 //setOwnerOf
2871 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2872 break;
2873
2874 case 0x02:
2875 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2876 break;
2877 case 0x42:
2878 case 0xC2:
2879 //startScript
2880 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2881 break;
2882
2883 case 0x1C:
2884 case 0x5C:
2885 case 0x9C:
2886 case 0xDC:
2887 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2888 break;
2889
2890 case 0x20:
2891 do_tok(buf, "stopMusic", 0);
2892 break;
2893 case 0x00:
2894 case 0xA0:
2895 do_tok(buf, "stopObjectCode", 0);
2896 break;
2897 case 0x62:
2898 case 0xE2:
2899 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2900 break;
2901
2902 case 0x3C:
2903 case 0xBC:
2904 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2905 break;
2906
2907 case 0x4C:
2908 case 0xCC:
2909 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
2910 break;
2911
2912 case 0x1E:
2913 case 0x3E:
2914 case 0x5E:
2915 case 0x7E:
2916 case 0x9E:
2917 case 0xBE:
2918 case 0xDE:
2919 case 0xFE:
2920 do_tok(buf, "walkActorTo",
2921 ((opcode & 0x80) ? A1V : A1B) |
2922 ((opcode & 0x40) ? A2V : A2B) |
2923 ((opcode & 0x20) ? A3V : A3B));
2924 break;
2925
2926 case 0x36:
2927 case 0xB6:
2928 case 0x76:
2929 case 0xF6:
2930 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | A2B);
2931 break;
2932
2933 default:
2934 error("Unknown opcode %.2X", opcode);
2935 }
2936}
2937
2938void next_line_V345(char *buf) {
2939 byte opcode = get_byte();
2940
2941 switch (opcode) {
2942
2943 case 0x00:
2944 case 0xA0:
2945 do_tok(buf, "stopObjectCode", 0);
2946 break;
2947
2948 case 0x01:
2949 case 0x21:
2950 case 0x41:
2951 case 0x61:
2952 case 0x81:
2953 case 0xA1:
2954 case 0xC1:
2955 case 0xE1:
2956 do_tok(buf, "putActor",
2957 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
2958 ((opcode & 0x20) ? A3V : A3W));
2959 break;
2960
2961 case 0x15:
2962 case 0x55:
2963 case 0x95:
2964 case 0xD5:
2965 do_tok(buf, "actorFromPos",
2966 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | AVARSTORE);
2967 break;
2968
2969 case 0x03:
2970 case 0x83:
2971 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2972 break;
2973
2974
2975 case 0x38:
2976 case 0xB8:
2977 case 0x04:
2978 case 0x84:
2979 case 0x08:
2980 case 0x88:
2981 case 0x48:
2982 case 0xC8:
2983 case 0x44:
2984 case 0xC4:
2985 case 0x78:
2986 case 0xF8:
2987 case 0x28:
2988 case 0xA8:
2989 do_if_code(buf, opcode);
2990 break;
2991
2992 case 0x05:
2993 case 0x45:
2994 case 0x85:
2995 case 0xC5:
2996 if (g_options.scriptVersion == 5) {
2997 buf = do_tok(buf, "drawObject", ((opcode & 0x80) ? A1V : A1W) | ANOLASTPAREN | ANOENDSEMICOLON);
2998 opcode = get_byte();
2999 switch (opcode & 0x1F) {
3000 case 1:
3001 do_tok(buf, "setXY",
3002 ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) |
3003 ((opcode & 0x40) ? A2V : A2W));
3004 break;
3005 case 2:
3006 do_tok(buf, "setImage", ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W));
3007 break;
3008 }
3009 strcat(buf, ");");
3010
3011 } else {
3012 buf = do_tok(buf, "drawObject",
3013 ((opcode & 0x80) ? A1V : A1W) |
3014 ((opcode & 0x40) ? A2V : A2W) |
3015 ((opcode & 0x20) ? A3V : A3W));
3016 }
3017 break;
3018
3019 case 0x25:
3020 case 0x65:
3021 case 0xA5:
3022 case 0xE5:
3023 if (g_options.scriptVersion == 5) {
3024 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3025 } else {
3026 buf = do_tok(buf, "drawObject",
3027 ((opcode & 0x80) ? A1V : A1W) |
3028 ((opcode & 0x40) ? A2V : A2W) |
3029 ((opcode & 0x20) ? A3V : A3W));
3030 }
3031 break;
3032
3033 case 0x06:
3034 case 0x86:
3035 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3036 break;
3037
3038 case 0x07:
3039 case 0x47:
3040 case 0x87:
3041 case 0xC7:
3042 do_tok(buf, "setState", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3043 break;
3044
3045 case 0x09:
3046 case 0x49:
3047 case 0x89:
3048 case 0xC9:
3049 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3050 break;
3051
3052 case 0x0A:
3053 case 0x8A:
3054 case 0x2A:
3055 case 0xAA:
3056 case 0x4A:
3057 case 0xCA:
3058 case 0x6A:
3059 case 0xEA:
3060 buf = do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST | ANOLASTPAREN | ANOENDSEMICOLON);
3061 if (opcode & 0x20) { // freeze resistant
3062 buf += sprintf(buf, ",F");
3063 }
3064 if (opcode & 0x40) { // recursive
3065 buf += sprintf(buf, ",R");
3066 }
3067 buf += sprintf(buf, ");");
3068 break;
3069
3070 case 0x0B:
3071 case 0x4B:
3072 case 0x8B:
3073 case 0xCB:
3074 do_tok(buf, "getVerbEntryPoint",
3075 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3076 break;
3077
3078 case 0x0c:
3079 case 0x8C:
3080 do_resource(buf, opcode);
3081 break;
3082
3083 case 0x0D:
3084 case 0x4D:
3085 case 0x8D:
3086 case 0xCD:
3087 do_tok(buf, "walkActorToActor",
3088 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
3089 break; /* arg1=actor, arg2=actor */
3090
3091 case 0x0F:
3092 case 0x8F:
3093 if (g_options.scriptVersion == 5) {
3094 do_tok(buf, "getObjectState", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3095 break;
3096 }
3097 case 0x2F:
3098 case 0x4F:
3099 case 0x6F:
3100 case 0xAF:
3101 case 0xCF:
3102 case 0xEF:
3103 do_if_state_code(buf, opcode);
3104 break;
3105
3106 case 0x10:
3107 case 0x90:
3108 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3109 break;
3110
3111
3112 case 0x14:
3113 case 0xD8:
3114 case 0x94:
3115 do_print_ego(buf, opcode);
3116 break;
3117
3118 case 0x17:
3119 case 0x97:
3120 case 0x1A:
3121 case 0x9A:
3122 case 0x1B:
3123 case 0x9B:
3124 case 0x3A:
3125 case 0xBA:
3126 case 0x46:
3127 case 0x57:
3128 case 0xD7:
3129 case 0x5A:
3130 case 0xDA:
3131 case 0x5B:
3132 case 0xDB:
3133 case 0xC6:
3134 do_varset_code(buf, opcode);
3135 break;
3136
3137 case 0x18:
3138 do_unconditional_jump(buf);
3139 break;
3140
3141 case 0x1D:
3142 case 0x9D:
3143 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | A2LIST | ATO | ATOWITHLASTPAREN);
3144 break; /* arg1=object; vararg=classes to test; arg3=jumpoffs */
3145
3146 case 0x1E:
3147 case 0x3E:
3148 case 0x5E:
3149 case 0x7E:
3150 case 0x9E:
3151 case 0xBE:
3152 case 0xDE:
3153 case 0xFE:
3154 do_tok(buf, "walkActorTo",
3155 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
3156 ((opcode & 0x20) ? A3V : A3W));
3157 break;
3158
3159 case 0x24:
3160 case 0x64:
3161 case 0xA4:
3162 case 0xE4:
3163 buf =
3164 do_tok(buf, "loadRoomWithEgo",
3165 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
3166 do_tok(buf, NULL, A1W | A2W | ANOFIRSTPAREN | ASTARTCOMMA);
3167 break;
3168
3169 case 0x2C:
3170 do_cursor_command(buf);
3171 break;
3172
3173 case 0x40:
3174 do_tok(buf, "cutscene", A1LIST);
3175 break;
3176
3177 case 0x42:
3178 case 0xC2:
3179 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST);
3180 break;
3181
3182 case 0x56:
3183 case 0xD6:
3184 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3185 break;
3186 case 0x72:
3187 case 0xF2:
3188 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
3189 break;
3190
3191 case 0x63:
3192 case 0xE3:
3193 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3194 break;
3195
3196 case 0x66:
3197 case 0xE6:
3198 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3199 break;
3200
3201 case 0x6C:
3202 case 0xEC:
3203 do_tok(buf, "getActorWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3204 break;
3205
3206 case 0x71:
3207 case 0xF1:
3208 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3209 break;
3210
3211 case 0x3B:
3212 case 0xBB:
3213 if (g_options.IndyFlag)
3214 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
3215 else
3216 do_tok(buf, "getActorScale", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3217 break;
3218
3219 case 0xAE:{
3220 if (g_options.IndyFlag)
3221 opcode = 2;
3222 else
3223 opcode = get_byte();
3224
3225 switch (opcode) {
3226 case 0x01:
3227 case 0x81:
3228 do_tok(buf, "WaitForActor", ((opcode & 0x80) ? A1V : A1B));
3229 break;
3230 case 0x02:
3231 do_tok(buf, "WaitForMessage", 0);
3232 break;
3233 case 0x03:
3234 do_tok(buf, "WaitForCamera", 0);
3235 break;
3236 case 0x04:
3237 do_tok(buf, "WaitForSentence", 0);
3238 break;
3239 default:
3240 do_tok(buf, "UnknownWait", 0);
3241 }
3242 }
3243 break;
3244
3245
3246 case 0x34:
3247 case 0x74:
3248 case 0xB4:
3249 case 0xF4:
3250 do_tok(buf, "getDist",
3251 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3252 break;
3253
3254
3255 case 0x36:
3256 case 0x76:
3257 case 0xB6:
3258 case 0xF6:
3259 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3260 break;
3261
3262 case 0x37:
3263 case 0x77:
3264 case 0xB7:
3265 case 0xF7:
3266 do_tok(buf, "startObject",
3267 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | A3LIST);
3268 break;
3269
3270 case 0x19:
3271 case 0x39:
3272 case 0x59:
3273 case 0x79:
3274 case 0x99:
3275 case 0xB9:
3276 case 0xD9:
3277 case 0xF9:{
3278 buf = strecpy(buf, "doSentence(");
3279 // FIXME: this is not exactly what ScummVM does...
3280 if (!(opcode & 0x80) && (*g_scriptCurPos == 0xFE)) {
3281 strcpy(buf, "STOP)");
3282 g_scriptCurPos++;
3283 } else {
3284 do_tok(buf, "",
3285 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
3286 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W));
3287 }
3288 }
3289 break;
3290
3291
3292 case 0x62:
3293 case 0xE2:
3294 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
3295 break;
3296
3297 case 0xAC:
3298 do_expr_code(buf);
3299 break;
3300
3301 case 0x11:
3302 case 0x51:
3303 case 0x91:
3304 case 0xD1:
3305 do_tok(buf, "animateCostume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3306 break;
3307
3308 case 0x80:
3309 do_tok(buf, "breakHere", 0);
3310 break;
3311
3312 case 0xc0:
3313 do_tok(buf, "endCutscene", 0);
3314 break;
3315
3316 case 0x27:{ /* String management subcode */
3317 switch ((opcode = get_byte()) & 0x1F) {
3318 case 0x01:
3319 do_load_code_to_string(buf, opcode);
3320 break;
3321 case 0x02:
3322 do_tok(buf, "CopyString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3323 break;
3324 case 0x03:
3325 do_tok(buf, "SetStringChar",
3326 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3327 ((opcode & 0x20) ? A3V : A3B));
3328 break; /* string(arg1)[arg2] = arg3 */
3329 case 0x04:
3330 do_tok(buf, "GetStringChar",
3331 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3332 break; /* arg1 = string(arg2)[arg3] */
3333 case 0x05:
3334 do_tok(buf, "CreateString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3335 break; /* arg1=index, arg2=size */
3336 default:
3337 do_tok(buf, "StringFuncUnknown", 0);
3338 }
3339 }
3340 break;
3341
3342 case 0x13:
3343 case 0x53:
3344 case 0x93:
3345 case 0xD3:
3346 do_actorops(buf, opcode);
3347 break;
3348
3349 case 0x20:
3350 do_tok(buf, "stopMusic", 0);
3351 break;
3352
3353 case 0x70:
3354 case 0xF0:
3355 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
3356 break;
3357
3358 case 0x3F:
3359 case 0x7F:
3360 case 0xBF:
3361 case 0xFF:
3362 buf =
3363 do_tok(buf, "drawBox",
3364 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOLASTPAREN);
3365 opcode = get_byte();
3366 do_tok(buf, NULL,
3367 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1W) |
3368 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3B));
3369 break;
3370
3371
3372 case 0x02:
3373 case 0x82:
3374 if (g_options.ZakFlag)
3375 do_tok(buf, "startMusic", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3376 else
3377 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
3378 break;
3379
3380 case 0xCC:
3381 do_pseudoRoom(buf);
3382 break;
3383
3384 case 0x33:
3385 case 0x73:
3386 case 0xB3:
3387 case 0xF3:
3388 if (g_options.scriptVersion == 5)
3389 do_room_ops(buf);
3390 else
3391 do_room_ops_old(buf, opcode);
3392 break;
3393
3394 case 0x68:
3395 case 0xE8:
3396 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3397 break;
3398
3399 case 0x2E:{
3400 int d;
3401 d = get_byte();
3402 d |= get_byte() << 8;
3403 d |= get_byte() << 16;
3404 sprintf(buf, "delay(%d);", d);
3405 break;
3406 }
3407
3408 case 0x29:
3409 case 0x69:
3410 case 0xA9:
3411 case 0xE9:
3412 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3413 break;
3414
3415 case 0x52:
3416 case 0xD2:
3417 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
3418 break;
3419
3420 case 0x58:{
3421 int d;
3422 d = get_byte();
3423 if (d != 0)
3424 sprintf(buf, "beginOverride();");
3425 else
3426 sprintf(buf, "endOverride();");
3427 break;
3428 }
3429
3430 case 0x1C:
3431 case 0x9C:
3432 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
3433 break;
3434
3435 case 0x4C:
3436 if (g_options.scriptVersion <= 3)
3437 do_tok(buf, "waitForSentence", 0);
3438 else
3439 do_tok(buf, "soundKludge", A1LIST);
3440 break;
3441
3442 case 0x3C:
3443 case 0xBC:
3444 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
3445 break;
3446
3447 case 0x98:
3448 do_tok(buf, "systemOps", A1B);
3449 break;
3450
3451 case 0x7B:
3452 case 0xFB:
3453 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3454 break;
3455
3456 case 0x43:
3457 case 0xC3:
3458 if (g_options.IndyFlag)
3459 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3460 else
3461 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3462 break;
3463
3464 case 0x23:
3465 case 0xA3:
3466 if (g_options.IndyFlag)
3467 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3468 else
3469 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3470 break;
3471
3472 case 0x7A:
3473 case 0xFA:
3474 do_verbops(buf, opcode);
3475 break;
3476
3477 case 0x2D:
3478 case 0x6D:
3479 case 0xAD:
3480 case 0xED:
3481 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3482 break;
3483
3484 case 0x54:
3485 case 0xD4:
3486 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
3487 break;
3488
3489 case 0x5D:
3490 case 0xDD:
3491 do_tok(buf, "setClass", ((opcode & 0x80) ? A1V : A1W) | A2LIST);
3492 break;
3493
3494 case 0x35:
3495 case 0x75:
3496 case 0xB5:
3497 case 0xF5:
3498 do_tok(buf, "findObject",
3499 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3500 break;
3501
3502 case 0x26:
3503 case 0xA6:{
3504 int i;
3505 char first = 1;
3506
3507 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN);
3508 i = get_byte();
3509
3510 buf += sprintf(buf, ",%d,[", i);
3511
3512 while (i > 0) {
3513 if (!first)
3514 buf = strecpy(buf, ",");
3515 first = 0;
3516
3517 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
3518 i--;
3519 }
3520
3521 strcpy(buf, "]);");
3522
3523 }
3524 break;
3525
3526 case 0x16:
3527 case 0x96:
3528 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3529 break;
3530
3531 case 0x2B:
3532 do_tok(buf, "delayVariable", A1V);
3533 break;
3534
3535 case 0x0E:
3536 case 0x4E:
3537 case 0x8E:
3538 case 0xCE:
3539 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3540 break;
3541
3542 case 0x12:
3543 case 0x92:
3544 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1W));
3545 break;
3546
3547 case 0x32:
3548 case 0xB2:
3549 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1W));
3550 break;
3551
3552 case 0x30:
3553 case 0xB0:
3554 if (g_options.scriptVersion == 3)
3555 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
3556 else
3557 do_matrix_ops(buf, opcode);
3558 break;
3559
3560 case 0x7C:
3561 case 0xFC:
3562 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3563 break;
3564
3565 case 0x31:
3566 case 0xB1:
3567 do_tok(buf, "getInventoryCount", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3568 break;
3569
3570 case 0x1f:
3571 case 0x5f:
3572 case 0x9f:
3573 case 0xdf:
3574 do_tok(buf, "isActorInBox",
3575 ATO | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3576 break;
3577
3578 case 0x22:
3579 case 0xA2:
3580 if (g_options.scriptVersion == 5)
3581 do_tok(buf, "getAnimCounter", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3582 else
3583 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3584 break;
3585
3586 case 0x3d:
3587 case 0x7d:
3588 case 0xBD:
3589 case 0xFD:
3590 do_tok(buf, "findInventory",
3591 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3592 break;
3593
3594 case 0xAB:{
3595 int code;
3596 opcode = get_byte();
3597 code =
3598 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3599 ((opcode & 0x20) ? A3V : A3B);
3600 switch (opcode & 0x1F) {
3601 case 0x01:
3602 do_tok(buf, "saveVerbs", code);
3603 break;
3604 case 0x02:
3605 do_tok(buf, "restoreVerbs", code);
3606 break;
3607 case 0x03:
3608 do_tok(buf, "deleteVerbs", code);
3609 break;
3610 default:
3611 error("opcode 0xAB: Unhandled subop %d", opcode & 0x1F);
3612 }
3613 }
3614 break;
3615
3616 case 0x60:
3617 case 0xE0:
3618 do_tok(buf, "freezeScripts", ((opcode & 0x80) ? A1V : A1B));
3619 break;
3620
3621 case 0x6E:
3622 case 0xEE:
3623 do_tok(buf, "stopObjectScript", ((opcode & 0x80) ? A1V : A1W));
3624 break;
3625
3626 // dodgy?
3627 case 0x5C:{
3628 case 0xDC:
3629 int d = get_byte();
3630 if ((d & 0x1F) == 3)
3631 do_tok(buf, "oldRoomEffect-set", ((opcode & 0x80) ? A1V : A1W));
3632 else
3633 do_tok(buf, "oldRoomEffect-fadein", ((opcode & 0x80) ? A1V : A1W));
3634 break;
3635 }
3636
3637 case 0x50:
3638 case 0xD0:
3639 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
3640 break;
3641
3642 case 0xA7:
3643 if (g_options.scriptVersion == 5) {
3644 sprintf(buf, "dummy(%.2X);", opcode);
3645 } else {
3646 int d = get_byte();
3647 buf += sprintf(buf, "saveLoadVars(");
3648 if (d == 1) {
3649 buf += sprintf(buf, "Save");
3650 } else {
3651 buf += sprintf(buf, "Load");
3652 }
3653 while ((d = get_byte()) != 0) {
3654 switch (d & 0x1F) {
3655 case 0x01:
3656 buf += sprintf(buf, ", VarRange(");
3657 buf = get_var(buf);
3658 buf += sprintf(buf, ",");
3659 buf = get_var(buf);
3660 buf += sprintf(buf, ")");
3661 break;
3662 case 0x02:
3663 buf += sprintf(buf, ", StringRange(");
3664 buf = get_var_or_byte(buf, (d & 0x80));
3665 buf += sprintf(buf, ",");
3666 buf = get_var_or_byte(buf, (d & 0x40));
3667 buf += sprintf(buf, ")");
3668 break;
3669 case 0x03:
3670 buf += sprintf(buf, ", Open(");
3671 buf = get_ascii(buf);
3672 buf += sprintf(buf, ")");
3673 break;
3674 case 0x04:
3675 buf += sprintf(buf, ", Append)");
3676 return;
3677 case 0x1F:
3678 buf += sprintf(buf, ", Close)");
3679 return;
3680 }
3681 }
3682 buf += sprintf(buf, ");");
3683 }
3684 break;
3685
3686 case 0x67:
3687 case 0xE7:
3688 do_tok(buf, "getStringWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3689 break;
3690
3691 case 0x6B:
3692 do_tok(buf, "debug", ((opcode & 0x80) ? A1V : A1W));
3693 break;
3694
3695 default:
3696 if (g_options.haltOnError) {
3697 error("Unknown opcode %.2X", opcode);
3698 }
3699 sprintf(buf, "ERROR: Unknown opcode %.2X!", opcode);
3700 }
3701}