Ticket #9091: descumm.cpp

File descumm.cpp, 79.8 KB (added by SF/jestar_jokin, 11 years ago)

In case I screwed up making the diff again

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 44332 2009-09-25 09:07:48Z 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 strecpy(strchr(buf2, 0), ">");
931 pushExprStack(buf);
932 break;
933
934 default:
935 printf("Warning, Invalid expression code %.2X\n", i);
936 }
937
938 } while (1);
939
940 strcpy(popExprStack(buf), ";");
941}
942
943
944void do_load_code_to_string(char *buf, byte opcode) {
945
946 buf = strchr(strcpy(buf, "PutCodeInString("), 0);
947 buf = get_var_or_byte(buf, opcode & 0x80);
948 buf = strchr(strcpy(buf, ", "), 0);
949 buf = get_ascii(buf);
950 strcpy(buf, ");");
951}
952
953void do_resource_v2(char *buf, byte opcode) {
954 const char *resTypes[] = {
955 "UnkResType0",
956 "UnkResType1",
957 "Costume",
958 "Room",
959 "UnkResType4",
960 "Script",
961 "Sound"
962 };
963 char resid[256];
964 int subop;
965
966 get_var_or_byte(resid, opcode & 0x80);
967 subop = get_byte();
968
969 int type = subop >> 4;
970
971 if (((subop & 0x0F) == 0) || ((subop & 0x0F) == 1)) {
972 if (subop & 1)
973 buf += sprintf(buf, "load");
974 else
975 buf += sprintf(buf, "nuke");
976 assert(0 <= type && type < ARRAYSIZE(resTypes));
977 buf += sprintf(buf, resTypes[type]);
978 buf += sprintf(buf, "(%s)", resid);
979 } else {
980 if (subop & 1)
981 buf += sprintf(buf, "lock");
982 else
983 buf += sprintf(buf, "unlock");
984 assert(0 <= type && type < ARRAYSIZE(resTypes));
985 buf += sprintf(buf, resTypes[type]);
986 buf += sprintf(buf, "(%s)", resid);
987 }
988}
989
990void do_resource(char *buf, byte opco) {
991 char opcode = get_byte();
992 int subop;
993 if (g_options.scriptVersion != 5)
994 subop = opcode & 0x3F; // FIXME - actually this should only be done for Zak256
995 else
996 subop = opcode & 0x1F;
997
998 buf += sprintf(buf, "Resource.");
999
1000 switch (subop) {
1001 case 0x1:
1002 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
1003 break;
1004 case 0x2:
1005 do_tok(buf, "loadSound", ((opcode & 0x80) ? A1V : A1B));
1006 break;
1007 case 0x3:
1008 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
1009 break;
1010 case 0x4:
1011 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
1012 break;
1013 case 0x5:
1014 do_tok(buf, "nukeScript", ((opcode & 0x80) ? A1V : A1B));
1015 break;
1016 case 0x6:
1017 do_tok(buf, "nukeSound", ((opcode & 0x80) ? A1V : A1B));
1018 break;
1019 case 0x7:
1020 do_tok(buf, "nukeCostume", ((opcode & 0x80) ? A1V : A1B));
1021 break;
1022 case 0x8:
1023 do_tok(buf, "nukeRoom", ((opcode & 0x80) ? A1V : A1B));
1024 break;
1025 case 0x9:
1026 do_tok(buf, "lockScript", ((opcode & 0x80) ? A1V : A1B));
1027 break;
1028 case 0xA:
1029 do_tok(buf, "lockSound", ((opcode & 0x80) ? A1V : A1B));
1030 break;
1031 case 0xB:
1032 do_tok(buf, "lockCostume", ((opcode & 0x80) ? A1V : A1B));
1033 break;
1034 case 0xC:
1035 do_tok(buf, "lockRoom", ((opcode & 0x80) ? A1V : A1B));
1036 break;
1037 case 0xD:
1038 do_tok(buf, "unlockScript", ((opcode & 0x80) ? A1V : A1B));
1039 break;
1040 case 0xE:
1041 do_tok(buf, "unlockSound", ((opcode & 0x80) ? A1V : A1B));
1042 break;
1043 case 0xF:
1044 do_tok(buf, "unlockCostume", ((opcode & 0x80) ? A1V : A1B));
1045 break;
1046 case 0x10:
1047 do_tok(buf, "unlockRoom", ((opcode & 0x80) ? A1V : A1B));
1048 break;
1049 case 0x11:
1050 do_tok(buf, "clearHeap", 0);
1051 break;
1052 case 0x12:
1053 do_tok(buf, "loadCharset", ((opcode & 0x80) ? A1V : A1B));
1054 break;
1055 case 0x13:
1056 do_tok(buf, "nukeCharset", ((opcode & 0x80) ? A1V : A1B));
1057 break;
1058 case 0x14:
1059 do_tok(buf, "loadFlObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
1060 break;
1061
1062 case 0x22 + 1:
1063 do_tok(buf, "setCDVolume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1064 break;
1065 case 0x23 + 1:
1066 do_tok(buf, "setSoundLoudness", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
1067 break;
1068 case 0x24 + 1:
1069 do_tok(buf, "setSoundPitch", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1070 break;
1071
1072
1073 default:
1074 error("do_resource: unhandled subop %d\n", subop);
1075 break;
1076 }
1077
1078}
1079
1080void do_pseudoRoom(char *buf) {
1081 int j, i = get_byte();
1082
1083 buf += sprintf(buf, "PseudoRoom(%d", i);
1084
1085 do {
1086 j = get_byte();
1087 if (!j)
1088 break;
1089
1090 if (j & 128)
1091 buf += sprintf(buf, ",%d", j & 127);
1092 else
1093 buf = strecpy(buf, ",IG");
1094 } while (1);
1095
1096 strcpy(buf, ");");
1097}
1098
1099void do_room_ops(char *buf) {
1100 int opcode = get_byte();
1101
1102 //buf+=sprintf(buf, "SubCode33%.2X", opcode);
1103
1104 switch (opcode & 0x1F) {
1105 case 0x01:
1106 do_tok(buf, "RoomScroll", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1107 break;
1108 case 0x02:
1109 do_tok(buf, "RoomColor", 0);
1110 break;
1111 case 0x03:
1112 do_tok(buf, "SetScreen", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1113 break;
1114 case 0x04:
1115 buf =
1116 do_tok(buf, "SetPalColor",
1117 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) |
1118 ((opcode & 0x20) ? A3V : A3W) | ANOLASTPAREN | ANOENDSEMICOLON);
1119 opcode = get_byte();
1120 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1121 break;
1122 case 0x05:
1123 do_tok(buf, "ShakeOn", 0);
1124 break;
1125 case 0x06:
1126 do_tok(buf, "ShakeOff", 0);
1127 break;
1128 case 0x07:
1129 // Possibly unused, but changed to match ScummVM anyway
1130 //do_tok(buf, "Unused", 0);
1131 buf = do_tok(buf, "SetRoomScale",
1132 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1133 ANOLASTPAREN | ANOENDSEMICOLON);
1134 opcode = get_byte();
1135 buf = do_tok(buf, NULL,
1136 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1137 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON);
1138 opcode = get_byte();
1139 buf = do_tok(buf, NULL,
1140 ((opcode & 0x40) ? A2V : A2B) | // apparently it uses the param 2 bit
1141 ASTARTCOMMA | ANOFIRSTPAREN);
1142 break;
1143 case 0x08:
1144 buf =
1145 do_tok(buf, "RoomIntensity",
1146 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1147 ((opcode & 0x20) ? A3V : A3B));
1148 break;
1149 case 0x09:
1150 buf = do_tok(buf, "saveLoad", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1151 break;
1152 case 0x0A:
1153 buf = do_tok(buf, "screenEffect", ((opcode & 0x80) ? A1V : A1W));
1154 break;
1155 case 0x0B:
1156 buf =
1157 do_tok(buf, "setRGBRoomIntensity",
1158 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1159 A2V : A2W) |
1160 ((opcode & 0x20) ? A3V : A3W));
1161 opcode = get_byte();
1162 buf =
1163 do_tok(buf, NULL,
1164 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1165 ((opcode & 0x40) ? A2V : A2B));
1166 break;
1167
1168 case 0x0C:
1169 buf =
1170 do_tok(buf, "setRoomShadow",
1171 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1172 A2V : A2W) |
1173 ((opcode & 0x20) ? A3V : A3W));
1174 opcode = get_byte();
1175 buf =
1176 do_tok(buf, NULL,
1177 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1178 ((opcode & 0x40) ? A2V : A2B));
1179 break;
1180
1181 case 0x0D:
1182 do_tok(buf, "saveString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1183 break;
1184 case 0x0E:
1185 do_tok(buf, "loadString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1186 break;
1187
1188 case 0x0F:
1189 buf = do_tok(buf, "palManipulate", ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1B));
1190 opcode = get_byte();
1191 buf =
1192 do_tok(buf, NULL,
1193 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ?
1194 A1V : A1B) |
1195 ((opcode & 0x40) ? A2V : A2B));
1196 opcode = get_byte();
1197 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1198 break;
1199
1200 case 0x10:
1201 do_tok(buf, "colorCycleDelay", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1202 break;
1203
1204 default:
1205 strcpy(buf, "Unknown??");
1206 }
1207}
1208
1209void do_room_ops_old(char *buf, byte opcode) {
1210 char a[256];
1211 char b[256];
1212
1213 if (g_options.scriptVersion <= 2) {
1214 get_var_or_byte(a, (opcode & 0x80));
1215 get_var_or_byte(b, (opcode & 0x40));
1216 } else if (g_options.scriptVersion == 3) {
1217 get_var_or_word(a, (opcode & 0x80));
1218 get_var_or_word(b, (opcode & 0x40));
1219 }
1220
1221 opcode = get_byte();
1222 switch (opcode & 0x1F) {
1223 case 0x01:
1224 if (g_options.scriptVersion > 3) {
1225 get_var_or_word(a, (opcode & 0x80));
1226 get_var_or_word(b, (opcode & 0x40));
1227 }
1228 buf = strecpy(buf, "RoomScroll(");
1229 buf = strecpy(buf, a);
1230 buf = strecpy(buf, ",");
1231 buf = strecpy(buf, b);
1232 buf = strecpy(buf, ")");
1233 break;
1234 case 0x02:
1235 if (g_options.scriptVersion > 3) {
1236 get_var_or_word(a, (opcode & 0x80));
1237 get_var_or_word(b, (opcode & 0x40));
1238 }
1239 buf = strecpy(buf, "RoomColor(");
1240 buf = strecpy(buf, a);
1241 buf = strecpy(buf, ",");
1242 buf = strecpy(buf, b);
1243 buf = strecpy(buf, ")");
1244 break;
1245 case 0x03:
1246 if (g_options.scriptVersion > 3) {
1247 get_var_or_word(a, (opcode & 0x80));
1248 get_var_or_word(b, (opcode & 0x40));
1249 }
1250 buf = strecpy(buf, "SetScreen(");
1251 buf = strecpy(buf, a);
1252 buf = strecpy(buf, ",");
1253 buf = strecpy(buf, b);
1254 buf = strecpy(buf, ")");
1255 break;
1256 case 0x04:
1257 if (g_options.scriptVersion > 3) {
1258 get_var_or_word(a, (opcode & 0x80));
1259 get_var_or_word(b, (opcode & 0x40));
1260 }
1261 buf = strecpy(buf, "SetPalColor(");
1262 buf = strecpy(buf, a);
1263 buf = strecpy(buf, ",");
1264 buf = strecpy(buf, b);
1265 buf = strecpy(buf, ")");
1266 break;
1267 case 0x05:
1268 do_tok(buf, "ShakeOn", 0);
1269 break;
1270 case 0x06:
1271 do_tok(buf, "ShakeOff", 0);
1272 break;
1273 default:
1274 error("do_room_ops_old: unknown subop %d", opcode & 0x1F);
1275 }
1276}
1277
1278void do_cursor_command(char *buf) {
1279 int opcode = get_byte();
1280
1281 switch (opcode & 0x1f) {
1282 case 0x01:
1283 do_tok(buf, "CursorShow", 0);
1284 break;
1285 case 0x02:
1286 do_tok(buf, "CursorHide", 0);
1287 break;
1288 case 0x03:
1289 do_tok(buf, "UserputOn", 0);
1290 break;
1291 case 0x04:
1292 do_tok(buf, "UserputOff", 0);
1293 break;
1294 case 0x05:
1295 do_tok(buf, "CursorSoftOn", 0);
1296 break;
1297 case 0x06:
1298 do_tok(buf, "CursorSoftOff", 0);
1299 break;
1300 case 0x07:
1301 do_tok(buf, "UserputSoftOn", 0);
1302 break;
1303 case 0x08:
1304 do_tok(buf, "UserputSoftOff", 0);
1305 break;
1306
1307 case 0x0A:
1308 do_tok(buf, "SetCursorImg", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1309 break;
1310 case 0x0B:
1311 do_tok(buf, "SetCursorHotspot",
1312 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1313 ((opcode & 0x20) ? A3V : A3B));
1314 break;
1315 case 0x0C:
1316 do_tok(buf, "InitCursor", ((opcode & 0x80) ? A1V : A1B));
1317 break;
1318 case 0x0D:
1319 do_tok(buf, "InitCharset", ((opcode & 0x80) ? A1V : A1B));
1320 break;
1321
1322 case 0x0E:
1323 if (g_options.scriptVersion == 3)
1324 do_tok(buf, "LoadCharset", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1325 else
1326 do_tok(buf, "CursorCommand", A1LIST);
1327 break;
1328 default:
1329 sprintf(buf, "UnknownCursorCommand%.2X", opcode);
1330 }
1331}
1332
1333void do_verbops_v2(char *buf, byte opcode) {
1334 int subop = get_byte();
1335
1336 buf = do_tok(buf, "VerbOps", ANOLASTPAREN | ANOENDSEMICOLON);
1337 switch (subop) {
1338 case 0:
1339 buf = do_tok(buf, "Delete", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1340 break;
1341 case 0xFF:
1342 buf = do_tok(buf, "State", A1B | A2B | ANOENDSEMICOLON);
1343 break;
1344 default:
1345 buf += sprintf(buf, "New-%d", subop);
1346 buf = do_tok(buf, "", A1B | A2B | ((opcode & 0x80) ? A3V : A3B) | A4B | A5ASCII | ANOENDSEMICOLON);
1347 }
1348 strecpy(buf, ");");
1349}
1350
1351void do_verbops(char *buf, byte opcode) {
1352 char first = 1;
1353
1354 buf = do_tok(buf, "VerbOps", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1355 buf = strecpy(buf, ",[");
1356
1357 do {
1358 opcode = get_byte();
1359 if (opcode == 0xFF)
1360 break;
1361 if (!first)
1362 buf = strecpy(buf, ",");
1363 first = 0;
1364 switch (opcode & 0x1F) {
1365 case 0x1:
1366 buf = do_tok(buf, "Image", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1367 break;
1368 case 0x2:
1369 buf = do_tok(buf, "Text", A1ASCII | ANOENDSEMICOLON);
1370 break;
1371 case 0x3:
1372 buf = do_tok(buf, "Color", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1373 break;
1374 case 0x4:
1375 buf = do_tok(buf, "HiColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1376 break;
1377 case 0x5:
1378 buf = do_tok(buf, "SetXY", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1379 break;
1380 case 0x6:
1381 buf = do_tok(buf, "On", ANOENDSEMICOLON);
1382 break;
1383 case 0x7:
1384 buf = do_tok(buf, "Off", ANOENDSEMICOLON);
1385 break;
1386 case 0x8:
1387 buf = do_tok(buf, "Delete", ANOENDSEMICOLON);
1388 break;
1389 case 0x9:
1390 buf = do_tok(buf, "New", ANOENDSEMICOLON);
1391 break;
1392 case 0x10:
1393 buf = do_tok(buf, "DimColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1394 break;
1395 case 0x11:
1396 buf = do_tok(buf, "Dim", ANOENDSEMICOLON);
1397 break;
1398 case 0x12:
1399 buf = do_tok(buf, "Key", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1400 break;
1401 case 0x13:
1402 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1403 break;
1404 case 0x14:
1405 buf = do_tok(buf, "SetToString", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1406 break;
1407 case 0x16:
1408 buf =
1409 do_tok(buf, "SetToObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
1410 break;
1411 case 0x17:
1412 buf = do_tok(buf, "BackColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1413 break;
1414 default:
1415 buf += sprintf(buf, "Invalid%.2X()", opcode);
1416 }
1417
1418 } while (1);
1419 strecpy(buf, "]);");
1420}
1421
1422void do_print_ego(char *buf, byte opcode) {
1423 char first = 1;
1424
1425 if (opcode == 0xD8) {
1426 buf = strecpy(buf, "printEgo([");
1427 } else {
1428 buf = do_tok(buf, "print", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1429 buf = strecpy(buf, ",[");
1430 }
1431
1432 do {
1433 opcode = get_byte();
1434 if (opcode == 0xFF)
1435 break;
1436
1437 if (!first)
1438 buf = strecpy(buf, ",");
1439 first = 0;
1440
1441 switch (opcode & 0x1f) {
1442 case 0x0:
1443 buf = do_tok(buf, "Pos", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1444 break;
1445 case 0x1:
1446 buf = do_tok(buf, "Color", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
1447 break;
1448 case 0x2:
1449 buf = do_tok(buf, "Clipped", ((opcode & 0x80) ? A1V : A1W) | ANOENDSEMICOLON);
1450 break;
1451 case 0x3:
1452 buf = do_tok(buf, "RestoreBG", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1453 break;
1454 case 0x4:
1455 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1456 break;
1457 case 0x6:
1458 if (g_options.GF_UNBLOCKED)
1459 buf = do_tok(buf, "Height", ((opcode & 0x80) ? A1V: A1W) | ANOENDSEMICOLON);
1460 else
1461 buf = do_tok(buf, "Left", ANOENDSEMICOLON);
1462 break;
1463 case 0x7:
1464 buf = do_tok(buf, "Overhead", ANOENDSEMICOLON);
1465 break;
1466 case 0x8:
1467 buf = do_tok(buf, "PlayCDTrack", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1468 break;
1469 case 0xF:{
1470 buf = strecpy(buf, "Text(");
1471 buf = get_ascii(buf);
1472 buf = strecpy(buf, ")");
1473 }
1474 goto exit_proc;
1475 default:
1476 buf += sprintf(buf, "Unknown%.2X()", opcode);
1477 goto exit_proc;
1478 }
1479 } while (1);
1480
1481exit_proc:;
1482 buf = strecpy(buf, "]);");
1483
1484}
1485
1486void do_unconditional_jump(char *buf) {
1487 int offset = get_word();
1488 int cur = get_curoffs();
1489 int to = cur + offset;
1490
1491 if (offset == 0) {
1492 sprintf(buf, "/* goto %.4X; */", to);
1493 } else if (!g_options.dontOutputElse && maybeAddElse(cur, to)) {
1494 pendingElse = true;
1495 pendingElseTo = to;
1496 pendingElseOffs = cur;
1497 pendingElseOpcode = g_jump_opcode;
1498 pendingElseIndent = g_blockStack.size();
1499 buf[0] = 0;
1500 } else {
1501 if (!g_blockStack.empty() && !g_options.dontOutputWhile) {
1502 Block p = g_blockStack.top();
1503 if (p.isWhile && cur == (int)p.to)
1504 return; // A 'while' ends here.
1505 }
1506 sprintf(buf, "goto %.4X;", to);
1507 }
1508}
1509
1510void emit_if(char *buf, char *condition) {
1511 int offset = get_word();
1512 int cur = get_curoffs();
1513 int to = cur + offset;
1514
1515 if (!g_options.dontOutputElseif && pendingElse) {
1516 if (maybeAddElseIf(cur, pendingElseTo, to)) {
1517 pendingElse = false;
1518 haveElse = true;
1519 buf = strecpy(buf, "} else if (");
1520 buf = strecpy(buf, condition);
1521 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1522 return;
1523 }
1524 }
1525
1526 if (!g_options.dontOutputIfs && maybeAddIf(cur, to)) {
1527 if (!g_options.dontOutputWhile && g_blockStack.top().isWhile) {
1528 buf = strecpy(buf, "while (");
1529 } else
1530 buf = strecpy(buf, "if (");
1531 buf = strecpy(buf, condition);
1532 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1533 return;
1534 }
1535
1536// buf = strecpy(buf, negate ? "if (" : "unless (");
1537 buf = strecpy(buf, "unless (");
1538 buf = strecpy(buf, condition);
1539 sprintf(buf, ") goto %.4X;", to);
1540}
1541
1542void do_if_code(char *buf, byte opcode) {
1543 char var[256];
1544 char tmp[256], tmp2[256];
1545 int txt;
1546
1547 const char *cmp_texts[8] = {
1548 " >= ", " < ", " <= ", " > ", " == ", " != ", "!", "",
1549 };
1550
1551 var[0] = 0;
1552 if (opcode != 0x28 && opcode != 0xA8)
1553 get_var(var);
1554
1555 switch (opcode & 0x7F) {
1556 case 0x38:
1557 txt = 0;
1558 break; /* lessOrEqual */
1559 case 0x04:
1560 txt = 2;
1561 break; /* isGreaterEqual */
1562 case 0x08:
1563 txt = 5;
1564 break; /* isNotEqual */
1565 case 0x48:
1566 txt = 4;
1567 break; /* isEqual */
1568 case 0x78:
1569 txt = 1;
1570 break; /* isGreater */
1571 case 0x44:
1572 txt = 3;
1573 break; /* isLess */
1574 case 0x28:
1575 txt = opcode & 128 ? 7 : 6;
1576 break;
1577 default:
1578 /* Exit, this should never happen, only if my code is buggy */
1579 error("Unknown IF code %x", opcode);
1580 }
1581
1582 if (opcode == 0x28 || opcode == 0xA8) {
1583 get_var(tmp2);
1584 } else {
1585 if (g_options.scriptVersion == 0)
1586 get_var_or_byte(tmp2, opcode & 0x80);
1587 else
1588 get_var_or_word(tmp2, opcode & 0x80);
1589 }
1590
1591 sprintf(tmp, "%s%s%s", var, cmp_texts[txt], tmp2);
1592 emit_if(buf, tmp);
1593}
1594
1595void do_if_active_object(char *buf, byte opcode) {
1596 char tmp[256];
1597
1598 int obj = get_byte();
1599 sprintf(tmp, "activeObject2 == %d", obj);
1600
1601 emit_if(buf, tmp);
1602}
1603
1604void do_if_state_code(char *buf, byte opcode) {
1605 char var[256];
1606 char tmp[256], tmp2[256];
1607 byte neg;
1608 int state = 0;
1609
1610 var[0] = 0;
1611 if (g_options.scriptVersion == 0) {
1612 if (opcode & 0x40)
1613 sprintf(var, "activeObject");
1614 else
1615 sprintf(var, "%d", get_byte());
1616 } else {
1617 get_var_or_word(var, opcode & 0x80);
1618 }
1619
1620 if (g_options.scriptVersion > 2) {
1621 switch (opcode & 0x2F) {
1622 case 0x0f:
1623 neg = 0;
1624 break;
1625 case 0x2f:
1626 neg = 1;
1627 break;
1628 default:
1629 /* Exit, this should never happen, only if my code is buggy */
1630 error("Unknown IF code %x", opcode);
1631 }
1632
1633 get_var_or_byte(tmp2, opcode & 0x40);
1634 } else {
1635 if (g_options.scriptVersion == 0) {
1636 switch (opcode) {
1637 case 0x7f:
1638 case 0xbf:
1639 state = 2;
1640 neg = 1;
1641 break;
1642 case 0x9f:
1643 case 0xdf:
1644 state = 4;
1645 neg = 1;
1646 break;
1647 case 0xaf:
1648 case 0xef:
1649 state = 8;
1650 neg = 1;
1651 break;
1652 case 0x3f:
1653 case 0xff:
1654 state = 2;
1655 neg = 0;
1656 break;
1657 case 0x1f:
1658 case 0x5f:
1659 state = 4;
1660 neg = 0;
1661 break;
1662 case 0x2f:
1663 case 0x6f:
1664 state = 8;
1665 neg = 0;
1666 break;
1667 default:
1668 /* Exit, this should never happen, only if my code is buggy */
1669 error("Unknown IF code %x", opcode);
1670 }
1671 } else {
1672 switch (opcode) {
1673 case 0x3f:
1674 case 0xbf:
1675 state = 1;
1676 neg = 1;
1677 break;
1678 case 0x5f:
1679 case 0xdf:
1680 state = 2;
1681 neg = 1;
1682 break;
1683 case 0x2f:
1684 case 0xaf:
1685 state = 4;
1686 neg = 1;
1687 break;
1688 case 0x0f:
1689 case 0x8f:
1690 state = 8;
1691 neg = 1;
1692 break;
1693 case 0x7f:
1694 case 0xff:
1695 state = 1;
1696 neg = 0;
1697 break;
1698 case 0x1f:
1699 case 0x9f:
1700 state = 2;
1701 neg = 0;
1702 break;
1703 case 0x6f:
1704 case 0xef:
1705 state = 4;
1706 neg = 0;
1707 break;
1708 case 0x4f:
1709 case 0xcf:
1710 state = 8;
1711 neg = 0;
1712 break;
1713 default:
1714 /* Exit, this should never happen, only if my code is buggy */
1715 error("Unknown IF code %x", opcode);
1716 }
1717 }
1718 }
1719
1720 if (g_options.scriptVersion > 2)
1721 sprintf(tmp, "getState(%s)%s%s", var, neg ? " != " : " == ", tmp2);
1722 else
1723 sprintf(tmp, "%sgetState%02d(%s)", neg ? "!" : "", state, var);
1724 emit_if(buf, tmp);
1725}
1726
1727void do_varset_code(char *buf, byte opcode) {
1728 const char *s;
1729
1730 if ((g_options.scriptVersion <= 2)
1731 && ((opcode & 0x7F) == 0x0A
1732 || (opcode & 0x7F) == 0x2A
1733 || (opcode & 0x7F) == 0x6A)) {
1734
1735 int i = get_byte();
1736 buf += sprintf(buf, "Var[Var[%d]]", i);
1737 } else
1738 buf = get_var(buf);
1739
1740 switch (opcode & 0x7F) {
1741 case 0x0A:
1742 case 0x1A:
1743 case 0x2C:
1744 s = " = ";
1745 break; /* move */
1746 case 0x1B:
1747 s = " *= ";
1748 break; /* mul */
1749 case 0x3A:
1750 case 0x6A:
1751 s = " -= ";
1752 break; /* sub */
1753 case 0x57:
1754 s = " |= ";
1755 break; /* or */
1756 case 0x2A:
1757 case 0x5A:
1758 s = " += ";
1759 break; /* add */
1760 case 0x5B:
1761 s = " /= ";
1762 break; /* divide */
1763 case 0x17:
1764 s = " &= ";
1765 break; /* and */
1766 case 0x46:
1767 if (opcode & 128)
1768 s = "--";
1769 else
1770 s = "++";
1771 break; /* increment & decrement */
1772 default:
1773 /* Exit, this should never happen, only if my code is buggy */
1774 error("Unknown VARSET code %x", opcode);
1775 }
1776
1777 buf = strecpy(buf, s);
1778
1779
1780 if ((g_options.scriptVersion <= 2) && (opcode & 0x7F) == 0x2C) { /* assignVarByte */
1781 sprintf(buf, "%d", get_byte());
1782 buf = strchr(buf, 0);
1783 } else if ((opcode & 0x7F) != 0x46) { /* increment or decrement */
1784 if (g_options.scriptVersion == 0)
1785 buf = get_var_or_byte(buf, opcode & 0x80);
1786 else
1787 buf = get_var_or_word(buf, opcode & 0x80);
1788 }
1789 strecpy(buf, ";");
1790}
1791
1792void do_matrix_ops(char *buf, byte opcode) {
1793 opcode = get_byte();
1794
1795 switch (opcode & 0x1F) {
1796 case 0x1:
1797 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1798 break;
1799 case 0x2:
1800 do_tok(buf, "setBoxScale", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1801 break;
1802 case 0x3:
1803 do_tok(buf, "SetBoxSlot", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1804 break;
1805 case 0x4:
1806 do_tok(buf, "createBoxMatrix", 0);
1807 break;
1808 default:
1809 sprintf(buf, "SetBoxUnknown%.2X;", opcode);
1810 }
1811}
1812
1813void next_line_V12(char *buf) {
1814 byte opcode = get_byte();
1815
1816 switch (opcode) {
1817
1818 case 0x58:
1819 do_tok(buf, "beginOverride", 0);
1820 break;
1821 case 0x52:
1822 case 0xD2:
1823 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
1824 break;
1825 case 0x15:
1826 case 0x55:
1827 case 0x95:
1828 case 0xD5:
1829 do_tok(buf, "actorFromPos",
1830 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
1831 break;
1832 case 0x13:
1833 case 0x53:
1834 case 0x93:
1835 case 0xD3:
1836 // actorSet
1837 do_actorops_v12(buf, opcode);
1838 break;
1839
1840 case 0x2A:
1841 case 0xAA:
1842 // addDirect
1843 case 0x3A:
1844 case 0xBA:
1845 //subtract
1846 case 0x6A:
1847 case 0xEA:
1848 //subDirect
1849 case 0x0A:
1850 case 0x8A:
1851 // assignVarWordDirect
1852 case 0x1A:
1853 case 0x5A:
1854 case 0x9A:
1855 case 0xDA:
1856 do_varset_code(buf, opcode);
1857 break;
1858
1859 case 0x11:
1860 case 0x51:
1861 case 0x91:
1862 case 0xD1:
1863 // animateActor
1864 do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1865 break;
1866 case 0x2C:
1867 // assignVarByte
1868 do_varset_code(buf, opcode);
1869 break;
1870 case 0x80:
1871 do_tok(buf, "breakHere", 0);
1872 break;
1873 case 0x4A:
1874 case 0xCA:
1875 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B));
1876 break;
1877
1878 case 0x60:
1879 case 0xE0:
1880 //do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1W));
1881 if (opcode & 0x80) {
1882 char tmp[256];
1883 get_var(tmp);
1884 buf += sprintf(buf, "cursorCommand(Hi(%s), Lo(%s));", tmp, tmp);
1885 } else {
1886 int val = get_word();
1887 buf += sprintf(buf, "cursorCommand(%d, %d);", (val >> 8) & 0xFF, val & 0xFF);
1888 }
1889
1890 break;
1891 case 0x40:
1892 sprintf(buf, "cutscene();");
1893 break;
1894 case 0xC0:
1895 sprintf(buf, "endCutscene();");
1896 break;
1897
1898 case 0x46:
1899 case 0xC6:
1900 // increment / decrement
1901 do_varset_code(buf, opcode);
1902 break;
1903
1904 case 0x2E: {
1905 //delay
1906 int d = get_byte();
1907 d |= get_byte() << 8;
1908 d |= get_byte() << 16;
1909 d = 0xFFFFFF - d;
1910 sprintf(buf, "delay(%d);", d);
1911 break;
1912 }
1913
1914 case 0x2B:
1915 do_tok(buf, "delayVariable", A1V);
1916 break;
1917
1918 case 0x19:
1919 case 0x39:
1920 case 0x59:
1921 case 0x79:
1922 case 0x99:
1923 case 0xB9:
1924 case 0xD9:
1925 case 0xF9:{
1926 buf = strecpy(buf, "doSentence(");
1927 if (!(opcode & 0x80) && *g_scriptCurPos == 0xFC) {
1928 strcpy(buf, "STOP)");
1929 g_scriptCurPos++;
1930 } else if (!(opcode & 0x80) && *g_scriptCurPos == 0xFB) {
1931 strcpy(buf, "RESET)");
1932 g_scriptCurPos++;
1933 } else {
1934 do_tok(buf, "",
1935 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1936 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W) | A4B);
1937 }
1938 }
1939 break;
1940
1941 case 0x05:
1942 case 0x25:
1943 case 0x45:
1944 case 0x65:
1945 case 0x85:
1946 case 0xA5:
1947 case 0xC5:
1948 case 0xE5:
1949 //drawObject
1950 buf = do_tok(buf, "drawObject",
1951 ((opcode & 0x80) ? A1V : A1W) |
1952 ((opcode & 0x40) ? A2V : A2B) |
1953 ((opcode & 0x20) ? A3V : A3B));
1954 break;
1955 case 0xAC:
1956 //drawSentence
1957 do_tok(buf, "drawSentence", 0);
1958 break;
1959 case 0x5C:
1960 case 0x6B:
1961 case 0x6E:
1962 case 0xAB:
1963 case 0xDC:
1964 case 0xEB:
1965 case 0xEE:
1966 //dummy
1967 sprintf(buf, "dummy(%.2X);", opcode);
1968
1969 break;
1970
1971 case 0x09:
1972 case 0x49:
1973 case 0x89:
1974 case 0xC9:
1975 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1976 break;
1977 case 0x35:
1978 case 0x75:
1979 case 0xB5:
1980 case 0xF5:
1981 do_tok(buf, "findObject",
1982 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1983 break;
1984 case 0x71:
1985 case 0xF1:
1986 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1987 break;
1988 case 0x06:
1989 case 0x86:
1990 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1991 break;
1992 case 0x63:
1993 case 0xE3:
1994 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1995 break;
1996 case 0x56:
1997 case 0xD6:
1998 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
1999 break;
2000 case 0x03:
2001 case 0x83:
2002 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2003 break;
2004 case 0x7B:
2005 case 0xFB:
2006 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2007 break;
2008 case 0x43:
2009 case 0xC3:
2010 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2011 break;
2012
2013 case 0x23:
2014 case 0xA3:
2015 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2016 break;
2017
2018 case 0x31:
2019 case 0xB1:
2020 do_tok(buf, "getBitVar", AVARSTORE | A1W | ((opcode & 0x80) ? A2V : A2B));
2021 break;
2022
2023 case 0x1B:
2024 case 0x5B:
2025 case 0x9B:
2026 case 0xDB:
2027 do_tok(buf, "setBitVar", A1W | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2028 break;
2029
2030 case 0x66:
2031 case 0xE6:
2032 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2033 break;
2034
2035 case 0x34:
2036 case 0x74:
2037 case 0xB4:
2038 case 0xF4:
2039 do_tok(buf, "getDist",
2040 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
2041 break;
2042 case 0x10:
2043 case 0x90:
2044 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2045 break;
2046 case 0x6C:
2047 case 0xEC:
2048 do_tok(buf, "getObjPreposition", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2049 break;
2050 case 0x16:
2051 case 0x96:
2052 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2053 break;
2054
2055 case 0x1D:
2056 case 0x5D:
2057 case 0x9D:
2058 case 0xDD:
2059 //ifClassOfIs
2060 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ATO | ATOWITHLASTPAREN);
2061 break;
2062
2063 case 0x3F:
2064 case 0xBF:
2065 //ifNotState01
2066 case 0x5F:
2067 case 0xDF:
2068 //ifNotState02
2069 case 0x2F:
2070 case 0xAF:
2071 //ifNotState04
2072 case 0x0F:
2073 case 0x8F:
2074 //ifNotState08
2075 case 0x7F:
2076 case 0xFF:
2077 //ifState01
2078 case 0x1F:
2079 case 0x9F:
2080 //ifState02
2081 case 0x6F:
2082 case 0xEF:
2083 //ifState04
2084 case 0x4F:
2085 case 0xCF:
2086 //ifState08
2087 do_if_state_code(buf, opcode);
2088 break;
2089
2090 case 0x48:
2091 case 0xC8:
2092 //isEqual
2093 case 0x78:
2094 case 0xF8:
2095 //isGreater
2096 case 0x04:
2097 case 0x84:
2098 //isGreaterEqual
2099 case 0x44:
2100 case 0xC4:
2101 //isLess
2102 case 0x08:
2103 case 0x88:
2104 //isNotEqual
2105 case 0x38:
2106 case 0xB8:
2107 //lessOrEqual
2108 case 0x28:
2109 //equalZero
2110 case 0xA8:
2111 //notEqualZero
2112 do_if_code(buf, opcode);
2113 break;
2114
2115 case 0x68:
2116 case 0xE8:
2117 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2118 break;
2119 case 0x7C:
2120 case 0xFC:
2121 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2122 break;
2123
2124 case 0x18:
2125 do_unconditional_jump(buf);
2126 break;
2127
2128 case 0x70:
2129 case 0xF0:
2130 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
2131 break;
2132 case 0x72:
2133 case 0xF2:
2134 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2135 break;
2136
2137 case 0x24:
2138 case 0x64:
2139 case 0xA4:
2140 case 0xE4:
2141 //loadRoomWithEgo
2142 buf =
2143 do_tok(buf, "loadRoomWithEgo",
2144 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
2145 do_tok(buf, NULL, A1B | A2B | ANOFIRSTPAREN | ASTARTCOMMA);
2146 break;
2147
2148 case 0x30:
2149 case 0xB0:
2150 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
2151 break;
2152
2153 case 0x12:
2154 case 0x92:
2155 //panCameraTo
2156 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2157 break;
2158 case 0x50:
2159 case 0xD0:
2160 //pickupObject
2161 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
2162 break;
2163 case 0x14:
2164 case 0x94:
2165 // print
2166 buf += sprintf(buf, "print(");
2167 buf = get_var_or_byte(buf, (opcode & 0x80));
2168 buf += sprintf(buf, ",\"");
2169 do_decodeparsestring_v2(buf, opcode);
2170 strcat(buf, "\");");
2171 break;
2172 case 0xD8:
2173 //printEgo
2174 buf += sprintf(buf, "printEgo(\"");
2175 do_decodeparsestring_v2(buf, opcode);
2176 strcat(buf, "\");");
2177 break;
2178
2179 case 0xCC:
2180 // pseudoRoom
2181 do_pseudoRoom(buf);
2182 break;
2183 case 0x01:
2184 case 0x21:
2185 case 0x41:
2186 case 0x61:
2187 case 0x81:
2188 case 0xA1:
2189 case 0xC1:
2190 case 0xE1:
2191 do_tok(buf, "putActor",
2192 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2193 ((opcode & 0x20) ? A3V : A3B));
2194 break;
2195 case 0x0E:
2196 case 0x4E:
2197 case 0x8E:
2198 case 0xCE:
2199 //putActorAtObject
2200 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) );
2201 break;
2202 case 0x2D:
2203 case 0x6D:
2204 case 0xAD:
2205 case 0xED:
2206 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2207 break;
2208 case 0x0C:
2209 case 0x8C:
2210 //resourceRoutines
2211 do_resource_v2(buf, opcode);
2212 break;
2213 case 0x98:
2214 do_tok(buf, "restart", 0);
2215 break;
2216
2217 case 0x33:
2218 case 0x73:
2219 case 0xB3:
2220 case 0xF3:
2221 do_room_ops_old(buf, opcode);
2222 break;
2223
2224 case 0x22:
2225 case 0xA2:
2226 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2227 break;
2228
2229 case 0x3D:
2230 case 0x7D:
2231 case 0xBD:
2232 case 0xFD:
2233 do_tok(buf, "setActorElevation", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2234 break;
2235
2236 case 0x32:
2237 case 0xB2:
2238 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2239 break;
2240
2241 case 0x54:
2242 case 0xD4:
2243 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
2244 break;
2245
2246 case 0x0B:
2247 case 0x4B:
2248 case 0x8B:
2249 case 0xCB:
2250 do_tok(buf, "setObjPreposition", ((opcode & 0x80) ? A1V : A1W) | A2B);
2251 break;
2252 case 0x29:
2253 case 0x69:
2254 case 0xA9:
2255 case 0xE9:
2256 //setOwnerOf
2257 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
2258 break;
2259
2260 case 0x77:
2261 case 0xF7:
2262 // clearState01
2263 do_tok(buf, "clearState01", ((opcode & 0x80) ? A1V : A1W));
2264 break;
2265 case 0x17:
2266 case 0x97:
2267 // clearState02
2268 do_tok(buf, "clearState02", ((opcode & 0x80) ? A1V : A1W));
2269 break;
2270 case 0x67:
2271 case 0xE7:
2272 // clearState04
2273 do_tok(buf, "clearState04", ((opcode & 0x80) ? A1V : A1W));
2274 break;
2275 case 0x47:
2276 case 0xC7:
2277 // clearState08
2278 do_tok(buf, "clearState08", ((opcode & 0x80) ? A1V : A1W));
2279 break;
2280
2281 case 0x37:
2282 case 0xB7:
2283 //setState01
2284 do_tok(buf, "setState01", ((opcode & 0x80) ? A1V : A1W));
2285 break;
2286 case 0x57:
2287 case 0xD7:
2288 //setState02
2289 do_tok(buf, "setState02", ((opcode & 0x80) ? A1V : A1W));
2290 break;
2291 case 0x27:
2292 case 0xA7:
2293 //setState04
2294 do_tok(buf, "setState04", ((opcode & 0x80) ? A1V : A1W));
2295 break;
2296 case 0x07:
2297 case 0x87:
2298 //setState08
2299 do_tok(buf, "setState08", ((opcode & 0x80) ? A1V : A1W));
2300 break;
2301
2302 case 0x26:
2303 case 0xA6: {
2304 int i;
2305 char first = 1;
2306
2307 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN);
2308 i = get_byte();
2309
2310 buf += sprintf(buf, ",%d,[", i);
2311
2312 while (i > 0) {
2313 if (!first)
2314 buf = strecpy(buf, ",");
2315 first = 0;
2316
2317 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
2318 i--;
2319 }
2320
2321 strcpy(buf, "]);");
2322
2323 }
2324 break;
2325
2326 case 0x02:
2327 case 0x82:
2328 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2329 break;
2330 case 0x42:
2331 case 0xC2:
2332 //startScript
2333 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2334 break;
2335
2336 case 0x1C:
2337 case 0x9C:
2338 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2339 break;
2340
2341 case 0x20:
2342 do_tok(buf, "stopMusic", 0);
2343 break;
2344 case 0x00:
2345 case 0xA0:
2346 do_tok(buf, "stopObjectCode", 0);
2347 break;
2348 case 0x62:
2349 case 0xE2:
2350 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2351 break;
2352
2353 case 0x3C:
2354 case 0xBC:
2355 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2356 break;
2357
2358 case 0x7A:
2359 case 0xFA:
2360 // verbOps
2361 do_verbops_v2(buf, opcode);
2362 break;
2363
2364 case 0x3B:
2365 case 0xBB:
2366 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
2367 break;
2368
2369 case 0x4C:
2370 do_tok(buf, "waitForSentence", 0);
2371 break;
2372
2373 case 0xAE:
2374 do_tok(buf, "waitForMessage", 0);
2375 break;
2376 case 0x1E:
2377 case 0x3E:
2378 case 0x5E:
2379 case 0x7E:
2380 case 0x9E:
2381 case 0xBE:
2382 case 0xDE:
2383 case 0xFE:
2384 do_tok(buf, "walkActorTo",
2385 ((opcode & 0x80) ? A1V : A1B) |
2386 ((opcode & 0x40) ? A2V : A2B) |
2387 ((opcode & 0x20) ? A3V : A3B));
2388 break;
2389
2390 case 0x0D:
2391 case 0x4D:
2392 case 0x8D:
2393 case 0xCD:
2394 do_tok(buf, "walkActorToActor",
2395 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2396 break;
2397 case 0x36:
2398 case 0x76:
2399 case 0xB6:
2400 case 0xF6:
2401 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
2402 break;
2403
2404 default:
2405 error("Unknown opcode %.2X", opcode);
2406 }
2407}
2408
2409void next_line_V0(char *buf) {
2410 byte opcode = get_byte();
2411
2412 switch (opcode) {
2413 case 0x05:
2414 case 0x09:
2415 case 0x0A:
2416 case 0x19:
2417 case 0x23:
2418 case 0x2C:
2419 case 0x35:
2420 case 0x39:
2421 case 0x3B:
2422 case 0x45:
2423 case 0x49:
2424 case 0x59:
2425 case 0x63:
2426 case 0x65:
2427 case 0x6A:
2428 case 0x6C:
2429 case 0x79:
2430 case 0x7A:
2431 case 0x7B:
2432 case 0x80:
2433 case 0x82:
2434 case 0x85:
2435 case 0x89:
2436 case 0x8A:
2437 case 0x8D:
2438 case 0x96:
2439 case 0x99:
2440 case 0xA3:
2441 case 0xA6:
2442 case 0xAA:
2443 case 0xAC:
2444 case 0xB5:
2445 case 0xB9:
2446 case 0xBB:
2447 case 0xC5:
2448 case 0xC9:
2449 case 0xD8:
2450 case 0xD9:
2451 case 0xE3:
2452 case 0xE6:
2453 case 0xEA:
2454 case 0xEC:
2455 case 0xF5:
2456 case 0xF9:
2457 case 0xFA:
2458 case 0xFB:
2459 do_tok(buf, "stopCurrentScript", 0);
2460 break;
2461
2462 case 0x67:
2463 case 0xE7:
2464 do_tok(buf, "getActorFacing", AVARSTORE | A1B | ((opcode & 0x80) ? A2V : A2B));
2465 break;
2466
2467 case 0x31:
2468 case 0x71:
2469 case 0xB1:
2470 case 0xF1:
2471 do_tok(buf, "getBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2472 break;
2473
2474 case 0x1D:
2475 case 0x3D:
2476 case 0x5D:
2477 case 0x7D:
2478 case 0x9D:
2479 case 0xBD:
2480 case 0xDD:
2481 case 0xFD:
2482 do_tok(buf, "setBitVar", A1B | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2483 break;
2484
2485 case 0x1B:
2486 case 0x5B:
2487 case 0x9B:
2488 case 0xDB:
2489 do_tok(buf, "getActorBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2490 break;
2491
2492 case 0x0B:
2493 case 0x2B:
2494 case 0x4B:
2495 case 0x6B:
2496 case 0x8B:
2497 case 0xAB:
2498 case 0xCB:
2499 case 0xEB:
2500 do_tok(buf, "setActorBitVar", A1B | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2501 break;
2502
2503 case 0x58:
2504 do_tok(buf, "beginOverride", 0);
2505 get_byte();
2506 get_byte();
2507 get_byte();
2508 break;
2509 case 0x52:
2510 case 0xD2:
2511 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
2512 break;
2513 case 0x95:
2514 case 0xD5:
2515 do_tok(buf, "actorFromPos",
2516 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
2517 break;
2518 case 0x15:
2519 case 0x55:
2520 do_tok(buf, "walkActorToActor",
2521 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2522 break; /* arg1=actor, arg2=actor */
2523 case 0x13:
2524 do_tok(buf, "lockCostume", A1B);
2525 break;
2526 case 0x4D:
2527 do_tok(buf, "lockRoom", A1B);
2528 break;
2529 case 0xCD:
2530 do_tok(buf, "unlockRoom", A1B);
2531 break;
2532 case 0x93:
2533 do_tok(buf, "unlockCostume", A1B);
2534 break;
2535 case 0x1A:
2536 case 0x9a:
2537 //move
2538 case 0x5A:
2539 case 0xDA:
2540 //add;
2541 case 0x3A:
2542 case 0xBA:
2543 //subtract
2544 do_varset_code(buf, opcode);
2545 break;
2546
2547 case 0x11:
2548 case 0x51:
2549 case 0x91:
2550 case 0xD1:
2551 buf = do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2552 break;
2553 case 0x10:
2554 do_tok(buf, "breakHere", 0);
2555 break;
2556 case 0x4A:
2557 case 0xCA:
2558 do_tok(buf, "loadRoom_c64", ((opcode & 0x80) ? A1V : A1B));
2559 break;
2560
2561 case 0x60:
2562 case 0xE0:
2563 //cursorCommand
2564 do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1B));
2565 break;
2566 case 0x40:
2567 do_tok(buf, "cutscene", 0);
2568 break;
2569 case 0xC0:
2570 do_tok(buf, "endCutscene", 0);
2571 break;
2572
2573 case 0x46:
2574 case 0xC6:
2575 // increment / decrement
2576 do_varset_code(buf, opcode);
2577 break;
2578
2579 case 0x2A: {
2580 //delay
2581 int d = get_byte();
2582 d |= get_byte() << 8;
2583 d |= get_byte() << 16;
2584 d = 0xFFFFFF - d;
2585 sprintf(buf, "delay(%d);", d);
2586 break;
2587 }
2588
2589 case 0x50:
2590 case 0x72:
2591 case 0xD0:
2592 case 0xF2:
2593 do_tok(buf, "nop", 0);
2594 break;
2595 case 0x14:
2596 case 0x94:
2597 // print
2598 buf += sprintf(buf, "print(");
2599 buf = get_var_or_byte(buf, (opcode & 0x80));
2600 buf += sprintf(buf, ",\"");
2601 do_decodeparsestring_v2(buf, opcode);
2602 strcat(buf, "\");");
2603 break;
2604 case 0x75:
2605 //printEgo
2606 buf += sprintf(buf, "printEgo(\"");
2607 do_decodeparsestring_v2(buf, opcode);
2608 strcat(buf, "\");");
2609 break;
2610 case 0x2E:
2611 case 0xAE:
2612 // print_c64
2613 buf += sprintf(buf, "print_c64(");
2614 buf = get_var_or_byte(buf, (opcode & 0x80));
2615 buf += sprintf(buf, ",\"");
2616 do_decodeparsestring_v2(buf, opcode);
2617 strcat(buf, "\");");
2618 break;
2619 case 0x0D:
2620 //printEgo_c64
2621 buf += sprintf(buf, "printEgo_c64(\"");
2622 do_decodeparsestring_v2(buf, opcode);
2623 strcat(buf, "\");");
2624 break;
2625
2626 case 0x2D:
2627 case 0x6D:
2628 case 0xAD:
2629 case 0xED:
2630 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2631 break;
2632 case 0xE5:
2633 do_tok(buf, "loadRoomWithEgo", A1B | A2B);
2634 break;
2635 case 0x6E:
2636 case 0xEE:
2637 //dummy
2638 sprintf(buf, "dummy%.2X();", opcode);
2639 break;
2640
2641 case 0x86:
2642 do_tok(buf, "bad", 0);
2643 break;
2644 case 0x56:
2645 case 0xD6:
2646 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2647 break;
2648 case 0x03:
2649 case 0x43:
2650 case 0x83:
2651 case 0xC3:
2652 do_tok(buf, "doSentence", A1B | A2B | A3B);
2653 break;
2654 case 0x07:
2655 case 0x87:
2656 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2657 break;
2658 case 0x47:
2659 case 0xC7:
2660 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2661 break;
2662
2663 case 0x27:
2664 case 0xA7:
2665 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2666 break;
2667
2668 case 0x26:
2669 do_tok(buf, "getClosestObjActor7", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2670 break;
2671 case 0x66:
2672 do_tok(buf, "getClosestObjActor25", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2673 break;
2674
2675 case 0x06:
2676 case 0x34:
2677 case 0x74:
2678 case 0xB4:
2679 case 0xF4:
2680 do_tok(buf, "getDist",
2681 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2682 break;
2683 case 0x90:
2684 do_tok(buf, "pickupObject", A1B);
2685 break;
2686 case 0x16:
2687 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2688 break;
2689
2690 case 0x0f:
2691 case 0x4f:
2692 do_tok(buf, "clearState02", ((opcode & 0x40) ? 0 : A1B));
2693 break;
2694 case 0x37:
2695 case 0x77:
2696 do_tok(buf, "clearState04", ((opcode & 0x40) ? 0 : A1B));
2697 break;
2698 case 0x17:
2699 case 0x57:
2700 do_tok(buf, "clearState08", ((opcode & 0x40) ? 0 : A1B));
2701 break;
2702 case 0x8f:
2703 case 0xcf:
2704 do_tok(buf, "setState02", ((opcode & 0x40) ? 0 : A1B));
2705 break;
2706 case 0xb7:
2707 case 0xf7:
2708 do_tok(buf, "setState04", ((opcode & 0x40) ? 0 : A1B));
2709 break;
2710 case 0x97:
2711 case 0xd7:
2712 do_tok(buf, "setState08", ((opcode & 0x40) ? 0 : A1B));
2713 break;
2714
2715 case 0x3f:
2716 case 0xff:
2717 //ifState02;
2718 case 0x1f:
2719 case 0x5f:
2720 //ifState04;
2721 case 0x2f:
2722 case 0x6f:
2723 //ifState08;
2724 case 0x7f:
2725 case 0xbf:
2726 //ifNotState02;
2727 case 0x9f:
2728 case 0xdf:
2729 //ifNotState04;
2730 case 0xaf:
2731 case 0xef:
2732 //ifNotState08;
2733 do_if_state_code(buf, opcode);
2734 break;
2735
2736 case 0x48:
2737 case 0xC8:
2738 //isEqual
2739 case 0x78:
2740 case 0xF8:
2741 //isGreater
2742 case 0x04:
2743 case 0x84:
2744 //isGreaterEqual
2745 case 0x44:
2746 case 0xC4:
2747 //isLess
2748 case 0x08:
2749 case 0x88:
2750 //isNotEqual
2751 case 0x38:
2752 case 0xB8:
2753 //lessOrEqual
2754 case 0x28:
2755 //equalZero
2756 case 0xA8:
2757 //notEqualZero
2758 do_if_code(buf, opcode);
2759 break;
2760
2761 case 0x68:
2762 case 0xE8:
2763 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2764 break;
2765 case 0x7C:
2766 case 0xFC:
2767 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2768 break;
2769
2770 case 0x53:
2771 do_tok(buf, "lockSound", A1B);
2772 break;
2773
2774 case 0xD3:
2775 do_tok(buf, "unlockSound", A1B);
2776 break;
2777
2778 case 0x18:
2779 do_unconditional_jump(buf);
2780 break;
2781
2782 case 0x70:
2783 case 0xF0:
2784 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B));
2785 break;
2786 case 0x25:
2787 case 0xA5:
2788 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2789 break;
2790
2791 case 0x24:
2792 case 0xA4:
2793 do_tok(buf, "unknown2", A1B);
2794 break;
2795 case 0x64:
2796 case 0xE4:
2797 do_if_active_object(buf, opcode);
2798 break;
2799
2800 case 0x30:
2801 case 0xB0:
2802 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
2803 break;
2804
2805 case 0x12:
2806 case 0x92:
2807 //panCameraTo
2808 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2809 break;
2810
2811 case 0x01:
2812 case 0x21:
2813 case 0x41:
2814 case 0x61:
2815 case 0x81:
2816 case 0xA1:
2817 case 0xC1:
2818 case 0xE1:
2819 do_tok(buf, "putActor",
2820 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2821 ((opcode & 0x20) ? A3V : A3B));
2822 break;
2823 case 0x4E:
2824 case 0xCE:
2825 case 0x0E:
2826 case 0x8E:
2827 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | A2B);
2828 break;
2829 case 0x0C:
2830 case 0x8C:
2831 do_tok(buf, "loadSound", A1B);
2832 break;
2833 case 0x98:
2834 do_tok(buf, "restart", 0);
2835 break;
2836
2837 case 0x33:
2838 do_tok(buf, "lockScript", A1B);
2839 break;
2840 case 0xB3:
2841 do_tok(buf, "unlockScript", A1B);
2842 break;
2843 case 0x73:
2844 case 0xF3:
2845 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2846 break;
2847
2848 case 0x22:
2849 case 0xA2:
2850 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2851 break;
2852
2853 case 0x32:
2854 case 0xB2:
2855 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2856 break;
2857
2858 case 0x54:
2859 case 0xD4:
2860 do_tok(buf, "setObjectName", A1B | A2ASCII);
2861 break;
2862
2863 case 0x29:
2864 case 0x69:
2865 case 0xA9:
2866 case 0xE9:
2867 //setOwnerOf
2868 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2869 break;
2870
2871 case 0x02:
2872 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2873 break;
2874 case 0x42:
2875 case 0xC2:
2876 //startScript
2877 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2878 break;
2879
2880 case 0x1C:
2881 case 0x5C:
2882 case 0x9C:
2883 case 0xDC:
2884 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2885 break;
2886
2887 case 0x20:
2888 do_tok(buf, "stopMusic", 0);
2889 break;
2890 case 0x00:
2891 case 0xA0:
2892 do_tok(buf, "stopObjectCode", 0);
2893 break;
2894 case 0x62:
2895 case 0xE2:
2896 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2897 break;
2898
2899 case 0x3C:
2900 case 0xBC:
2901 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2902 break;
2903
2904 case 0x4C:
2905 case 0xCC:
2906 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
2907 break;
2908
2909 case 0x1E:
2910 case 0x3E:
2911 case 0x5E:
2912 case 0x7E:
2913 case 0x9E:
2914 case 0xBE:
2915 case 0xDE:
2916 case 0xFE:
2917 do_tok(buf, "walkActorTo",
2918 ((opcode & 0x80) ? A1V : A1B) |
2919 ((opcode & 0x40) ? A2V : A2B) |
2920 ((opcode & 0x20) ? A3V : A3B));
2921 break;
2922
2923 case 0x36:
2924 case 0xB6:
2925 case 0x76:
2926 case 0xF6:
2927 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | A2B);
2928 break;
2929
2930 default:
2931 error("Unknown opcode %.2X", opcode);
2932 }
2933}
2934
2935void next_line_V345(char *buf) {
2936 byte opcode = get_byte();
2937
2938 switch (opcode) {
2939
2940 case 0x00:
2941 case 0xA0:
2942 do_tok(buf, "stopObjectCode", 0);
2943 break;
2944
2945 case 0x01:
2946 case 0x21:
2947 case 0x41:
2948 case 0x61:
2949 case 0x81:
2950 case 0xA1:
2951 case 0xC1:
2952 case 0xE1:
2953 do_tok(buf, "putActor",
2954 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
2955 ((opcode & 0x20) ? A3V : A3W));
2956 break;
2957
2958 case 0x15:
2959 case 0x55:
2960 case 0x95:
2961 case 0xD5:
2962 do_tok(buf, "actorFromPos",
2963 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | AVARSTORE);
2964 break;
2965
2966 case 0x03:
2967 case 0x83:
2968 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2969 break;
2970
2971
2972 case 0x38:
2973 case 0xB8:
2974 case 0x04:
2975 case 0x84:
2976 case 0x08:
2977 case 0x88:
2978 case 0x48:
2979 case 0xC8:
2980 case 0x44:
2981 case 0xC4:
2982 case 0x78:
2983 case 0xF8:
2984 case 0x28:
2985 case 0xA8:
2986 do_if_code(buf, opcode);
2987 break;
2988
2989 case 0x05:
2990 case 0x45:
2991 case 0x85:
2992 case 0xC5:
2993 if (g_options.scriptVersion == 5) {
2994 buf = do_tok(buf, "drawObject", ((opcode & 0x80) ? A1V : A1W) | ANOLASTPAREN | ANOENDSEMICOLON);
2995 opcode = get_byte();
2996 switch (opcode & 0x1F) {
2997 case 1:
2998 do_tok(buf, "setXY",
2999 ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) |
3000 ((opcode & 0x40) ? A2V : A2W));
3001 break;
3002 case 2:
3003 do_tok(buf, "setImage", ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W));
3004 break;
3005 }
3006 strcat(buf, ");");
3007
3008 } else {
3009 buf = do_tok(buf, "drawObject",
3010 ((opcode & 0x80) ? A1V : A1W) |
3011 ((opcode & 0x40) ? A2V : A2W) |
3012 ((opcode & 0x20) ? A3V : A3W));
3013 }
3014 break;
3015
3016 case 0x25:
3017 case 0x65:
3018 case 0xA5:
3019 case 0xE5:
3020 if (g_options.scriptVersion == 5) {
3021 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3022 } else {
3023 buf = do_tok(buf, "drawObject",
3024 ((opcode & 0x80) ? A1V : A1W) |
3025 ((opcode & 0x40) ? A2V : A2W) |
3026 ((opcode & 0x20) ? A3V : A3W));
3027 }
3028 break;
3029
3030 case 0x06:
3031 case 0x86:
3032 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3033 break;
3034
3035 case 0x07:
3036 case 0x47:
3037 case 0x87:
3038 case 0xC7:
3039 do_tok(buf, "setState", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3040 break;
3041
3042 case 0x09:
3043 case 0x49:
3044 case 0x89:
3045 case 0xC9:
3046 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3047 break;
3048
3049 case 0x0A:
3050 case 0x8A:
3051 case 0x2A:
3052 case 0xAA:
3053 case 0x4A:
3054 case 0xCA:
3055 case 0x6A:
3056 case 0xEA:
3057 buf = do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST | ANOLASTPAREN | ANOENDSEMICOLON);
3058 if (opcode & 0x20) { // freeze resistant
3059 buf += sprintf(buf, ",F");
3060 }
3061 if (opcode & 0x40) { // recursive
3062 buf += sprintf(buf, ",R");
3063 }
3064 buf += sprintf(buf, ");");
3065 break;
3066
3067 case 0x0B:
3068 case 0x4B:
3069 case 0x8B:
3070 case 0xCB:
3071 do_tok(buf, "getVerbEntryPoint",
3072 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3073 break;
3074
3075 case 0x0c:
3076 case 0x8C:
3077 do_resource(buf, opcode);
3078 break;
3079
3080 case 0x0D:
3081 case 0x4D:
3082 case 0x8D:
3083 case 0xCD:
3084 do_tok(buf, "walkActorToActor",
3085 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
3086 break; /* arg1=actor, arg2=actor */
3087
3088 case 0x0F:
3089 case 0x8F:
3090 if (g_options.scriptVersion == 5) {
3091 do_tok(buf, "getObjectState", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3092 break;
3093 }
3094 case 0x2F:
3095 case 0x4F:
3096 case 0x6F:
3097 case 0xAF:
3098 case 0xCF:
3099 case 0xEF:
3100 do_if_state_code(buf, opcode);
3101 break;
3102
3103 case 0x10:
3104 case 0x90:
3105 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3106 break;
3107
3108
3109 case 0x14:
3110 case 0xD8:
3111 case 0x94:
3112 do_print_ego(buf, opcode);
3113 break;
3114
3115 case 0x17:
3116 case 0x97:
3117 case 0x1A:
3118 case 0x9A:
3119 case 0x1B:
3120 case 0x9B:
3121 case 0x3A:
3122 case 0xBA:
3123 case 0x46:
3124 case 0x57:
3125 case 0xD7:
3126 case 0x5A:
3127 case 0xDA:
3128 case 0x5B:
3129 case 0xDB:
3130 case 0xC6:
3131 do_varset_code(buf, opcode);
3132 break;
3133
3134 case 0x18:
3135 do_unconditional_jump(buf);
3136 break;
3137
3138 case 0x1D:
3139 case 0x9D:
3140 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | A2LIST | ATO | ATOWITHLASTPAREN);
3141 break; /* arg1=object; vararg=classes to test; arg3=jumpoffs */
3142
3143 case 0x1E:
3144 case 0x3E:
3145 case 0x5E:
3146 case 0x7E:
3147 case 0x9E:
3148 case 0xBE:
3149 case 0xDE:
3150 case 0xFE:
3151 do_tok(buf, "walkActorTo",
3152 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
3153 ((opcode & 0x20) ? A3V : A3W));
3154 break;
3155
3156 case 0x24:
3157 case 0x64:
3158 case 0xA4:
3159 case 0xE4:
3160 buf =
3161 do_tok(buf, "loadRoomWithEgo",
3162 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
3163 do_tok(buf, NULL, A1W | A2W | ANOFIRSTPAREN | ASTARTCOMMA);
3164 break;
3165
3166 case 0x2C:
3167 do_cursor_command(buf);
3168 break;
3169
3170 case 0x40:
3171 do_tok(buf, "cutscene", A1LIST);
3172 break;
3173
3174 case 0x42:
3175 case 0xC2:
3176 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST);
3177 break;
3178
3179 case 0x56:
3180 case 0xD6:
3181 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3182 break;
3183 case 0x72:
3184 case 0xF2:
3185 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
3186 break;
3187
3188 case 0x63:
3189 case 0xE3:
3190 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3191 break;
3192
3193 case 0x66:
3194 case 0xE6:
3195 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3196 break;
3197
3198 case 0x6C:
3199 case 0xEC:
3200 do_tok(buf, "getActorWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3201 break;
3202
3203 case 0x71:
3204 case 0xF1:
3205 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3206 break;
3207
3208 case 0x3B:
3209 case 0xBB:
3210 if (g_options.IndyFlag)
3211 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
3212 else
3213 do_tok(buf, "getActorScale", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3214 break;
3215
3216 case 0xAE:{
3217 if (g_options.IndyFlag)
3218 opcode = 2;
3219 else
3220 opcode = get_byte();
3221
3222 switch (opcode) {
3223 case 0x01:
3224 case 0x81:
3225 do_tok(buf, "WaitForActor", ((opcode & 0x80) ? A1V : A1B));
3226 break;
3227 case 0x02:
3228 do_tok(buf, "WaitForMessage", 0);
3229 break;
3230 case 0x03:
3231 do_tok(buf, "WaitForCamera", 0);
3232 break;
3233 case 0x04:
3234 do_tok(buf, "WaitForSentence", 0);
3235 break;
3236 default:
3237 do_tok(buf, "UnknownWait", 0);
3238 }
3239 }
3240 break;
3241
3242
3243 case 0x34:
3244 case 0x74:
3245 case 0xB4:
3246 case 0xF4:
3247 do_tok(buf, "getDist",
3248 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3249 break;
3250
3251
3252 case 0x36:
3253 case 0x76:
3254 case 0xB6:
3255 case 0xF6:
3256 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3257 break;
3258
3259 case 0x37:
3260 case 0x77:
3261 case 0xB7:
3262 case 0xF7:
3263 do_tok(buf, "startObject",
3264 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | A3LIST);
3265 break;
3266
3267 case 0x19:
3268 case 0x39:
3269 case 0x59:
3270 case 0x79:
3271 case 0x99:
3272 case 0xB9:
3273 case 0xD9:
3274 case 0xF9:{
3275 buf = strecpy(buf, "doSentence(");
3276 // FIXME: this is not exactly what ScummVM does...
3277 if (!(opcode & 0x80) && (*g_scriptCurPos == 0xFE)) {
3278 strcpy(buf, "STOP)");
3279 g_scriptCurPos++;
3280 } else {
3281 do_tok(buf, "",
3282 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
3283 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W));
3284 }
3285 }
3286 break;
3287
3288
3289 case 0x62:
3290 case 0xE2:
3291 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
3292 break;
3293
3294 case 0xAC:
3295 do_expr_code(buf);
3296 break;
3297
3298 case 0x11:
3299 case 0x51:
3300 case 0x91:
3301 case 0xD1:
3302 do_tok(buf, "animateCostume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3303 break;
3304
3305 case 0x80:
3306 do_tok(buf, "breakHere", 0);
3307 break;
3308
3309 case 0xc0:
3310 do_tok(buf, "endCutscene", 0);
3311 break;
3312
3313 case 0x27:{ /* String management subcode */
3314 switch ((opcode = get_byte()) & 0x1F) {
3315 case 0x01:
3316 do_load_code_to_string(buf, opcode);
3317 break;
3318 case 0x02:
3319 do_tok(buf, "CopyString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3320 break;
3321 case 0x03:
3322 do_tok(buf, "SetStringChar",
3323 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3324 ((opcode & 0x20) ? A3V : A3B));
3325 break; /* string(arg1)[arg2] = arg3 */
3326 case 0x04:
3327 do_tok(buf, "GetStringChar",
3328 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3329 break; /* arg1 = string(arg2)[arg3] */
3330 case 0x05:
3331 do_tok(buf, "CreateString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3332 break; /* arg1=index, arg2=size */
3333 default:
3334 do_tok(buf, "StringFuncUnknown", 0);
3335 }
3336 }
3337 break;
3338
3339 case 0x13:
3340 case 0x53:
3341 case 0x93:
3342 case 0xD3:
3343 do_actorops(buf, opcode);
3344 break;
3345
3346 case 0x20:
3347 do_tok(buf, "stopMusic", 0);
3348 break;
3349
3350 case 0x70:
3351 case 0xF0:
3352 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
3353 break;
3354
3355 case 0x3F:
3356 case 0x7F:
3357 case 0xBF:
3358 case 0xFF:
3359 buf =
3360 do_tok(buf, "drawBox",
3361 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOLASTPAREN);
3362 opcode = get_byte();
3363 do_tok(buf, NULL,
3364 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1W) |
3365 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3B));
3366 break;
3367
3368
3369 case 0x02:
3370 case 0x82:
3371 if (g_options.ZakFlag)
3372 do_tok(buf, "startMusic", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3373 else
3374 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
3375 break;
3376
3377 case 0xCC:
3378 do_pseudoRoom(buf);
3379 break;
3380
3381 case 0x33:
3382 case 0x73:
3383 case 0xB3:
3384 case 0xF3:
3385 if (g_options.scriptVersion == 5)
3386 do_room_ops(buf);
3387 else
3388 do_room_ops_old(buf, opcode);
3389 break;
3390
3391 case 0x68:
3392 case 0xE8:
3393 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3394 break;
3395
3396 case 0x2E:{
3397 int d;
3398 d = get_byte();
3399 d |= get_byte() << 8;
3400 d |= get_byte() << 16;
3401 sprintf(buf, "delay(%d);", d);
3402 break;
3403 }
3404
3405 case 0x29:
3406 case 0x69:
3407 case 0xA9:
3408 case 0xE9:
3409 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3410 break;
3411
3412 case 0x52:
3413 case 0xD2:
3414 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
3415 break;
3416
3417 case 0x58:{
3418 int d;
3419 d = get_byte();
3420 if (d != 0)
3421 sprintf(buf, "beginOverride();");
3422 else
3423 sprintf(buf, "endOverride();");
3424 break;
3425 }
3426
3427 case 0x1C:
3428 case 0x9C:
3429 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
3430 break;
3431
3432 case 0x4C:
3433 if (g_options.scriptVersion <= 3)
3434 do_tok(buf, "waitForSentence", 0);
3435 else
3436 do_tok(buf, "soundKludge", A1LIST);
3437 break;
3438
3439 case 0x3C:
3440 case 0xBC:
3441 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
3442 break;
3443
3444 case 0x98:
3445 do_tok(buf, "systemOps", A1B);
3446 break;
3447
3448 case 0x7B:
3449 case 0xFB:
3450 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3451 break;
3452
3453 case 0x43:
3454 case 0xC3:
3455 if (g_options.IndyFlag)
3456 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3457 else
3458 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3459 break;
3460
3461 case 0x23:
3462 case 0xA3:
3463 if (g_options.IndyFlag)
3464 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3465 else
3466 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3467 break;
3468
3469 case 0x7A:
3470 case 0xFA:
3471 do_verbops(buf, opcode);
3472 break;
3473
3474 case 0x2D:
3475 case 0x6D:
3476 case 0xAD:
3477 case 0xED:
3478 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3479 break;
3480
3481 case 0x54:
3482 case 0xD4:
3483 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
3484 break;
3485
3486 case 0x5D:
3487 case 0xDD:
3488 do_tok(buf, "setClass", ((opcode & 0x80) ? A1V : A1W) | A2LIST);
3489 break;
3490
3491 case 0x35:
3492 case 0x75:
3493 case 0xB5:
3494 case 0xF5:
3495 do_tok(buf, "findObject",
3496 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3497 break;
3498
3499 case 0x26:
3500 case 0xA6:{
3501 int i;
3502 char first = 1;
3503
3504 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN);
3505 i = get_byte();
3506
3507 buf += sprintf(buf, ",%d,[", i);
3508
3509 while (i > 0) {
3510 if (!first)
3511 buf = strecpy(buf, ",");
3512 first = 0;
3513
3514 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
3515 i--;
3516 }
3517
3518 strcpy(buf, "]);");
3519
3520 }
3521 break;
3522
3523 case 0x16:
3524 case 0x96:
3525 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3526 break;
3527
3528 case 0x2B:
3529 do_tok(buf, "delayVariable", A1V);
3530 break;
3531
3532 case 0x0E:
3533 case 0x4E:
3534 case 0x8E:
3535 case 0xCE:
3536 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3537 break;
3538
3539 case 0x12:
3540 case 0x92:
3541 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1W));
3542 break;
3543
3544 case 0x32:
3545 case 0xB2:
3546 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1W));
3547 break;
3548
3549 case 0x30:
3550 case 0xB0:
3551 if (g_options.scriptVersion == 3)
3552 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
3553 else
3554 do_matrix_ops(buf, opcode);
3555 break;
3556
3557 case 0x7C:
3558 case 0xFC:
3559 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3560 break;
3561
3562 case 0x31:
3563 case 0xB1:
3564 do_tok(buf, "getInventoryCount", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3565 break;
3566
3567 case 0x1f:
3568 case 0x5f:
3569 case 0x9f:
3570 case 0xdf:
3571 do_tok(buf, "isActorInBox",
3572 ATO | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3573 break;
3574
3575 case 0x22:
3576 case 0xA2:
3577 if (g_options.scriptVersion == 5)
3578 do_tok(buf, "getAnimCounter", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3579 else
3580 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3581 break;
3582
3583 case 0x3d:
3584 case 0x7d:
3585 case 0xBD:
3586 case 0xFD:
3587 do_tok(buf, "findInventory",
3588 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3589 break;
3590
3591 case 0xAB:{
3592 int code;
3593 opcode = get_byte();
3594 code =
3595 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3596 ((opcode & 0x20) ? A3V : A3B);
3597 switch (opcode & 0x1F) {
3598 case 0x01:
3599 do_tok(buf, "saveVerbs", code);
3600 break;
3601 case 0x02:
3602 do_tok(buf, "restoreVerbs", code);
3603 break;
3604 case 0x03:
3605 do_tok(buf, "deleteVerbs", code);
3606 break;
3607 default:
3608 error("opcode 0xAB: Unhandled subop %d", opcode & 0x1F);
3609 }
3610 }
3611 break;
3612
3613 case 0x60:
3614 case 0xE0:
3615 do_tok(buf, "freezeScripts", ((opcode & 0x80) ? A1V : A1B));
3616 break;
3617
3618 case 0x6E:
3619 case 0xEE:
3620 do_tok(buf, "stopObjectScript", ((opcode & 0x80) ? A1V : A1W));
3621 break;
3622
3623 // dodgy?
3624 case 0x5C:{
3625 case 0xDC:
3626 int d = get_byte();
3627 if ((d & 0x1F) == 3)
3628 do_tok(buf, "oldRoomEffect-set", ((opcode & 0x80) ? A1V : A1W));
3629 else
3630 do_tok(buf, "oldRoomEffect-fadein", ((opcode & 0x80) ? A1V : A1W));
3631 break;
3632 }
3633
3634 case 0x50:
3635 case 0xD0:
3636 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
3637 break;
3638
3639 case 0xA7:
3640 if (g_options.scriptVersion == 5) {
3641 sprintf(buf, "dummy(%.2X);", opcode);
3642 } else {
3643 int d = get_byte();
3644 buf += sprintf(buf, "saveLoadVars(");
3645 if (d == 1) {
3646 buf += sprintf(buf, "Save");
3647 } else {
3648 buf += sprintf(buf, "Load");
3649 }
3650 while ((d = get_byte()) != 0) {
3651 switch (d & 0x1F) {
3652 case 0x01:
3653 buf += sprintf(buf, ", VarRange(");
3654 buf = get_var(buf);
3655 buf += sprintf(buf, ",");
3656 buf = get_var(buf);
3657 buf += sprintf(buf, ")");
3658 break;
3659 case 0x02:
3660 buf += sprintf(buf, ", StringRange(");
3661 buf = get_var_or_byte(buf, (d & 0x80));
3662 buf += sprintf(buf, ",");
3663 buf = get_var_or_byte(buf, (d & 0x40));
3664 buf += sprintf(buf, ")");
3665 break;
3666 case 0x03:
3667 buf += sprintf(buf, ", Open(");
3668 buf = get_ascii(buf);
3669 buf += sprintf(buf, ")");
3670 break;
3671 case 0x04:
3672 buf += sprintf(buf, ", Append)");
3673 return;
3674 case 0x1F:
3675 buf += sprintf(buf, ", Close)");
3676 return;
3677 }
3678 }
3679 buf += sprintf(buf, ");");
3680 }
3681 break;
3682
3683 case 0x67:
3684 case 0xE7:
3685 do_tok(buf, "getStringWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3686 break;
3687
3688 case 0x6B:
3689 do_tok(buf, "debug", ((opcode & 0x80) ? A1V : A1W));
3690 break;
3691
3692 default:
3693 if (g_options.haltOnError) {
3694 error("Unknown opcode %.2X", opcode);
3695 }
3696 sprintf(buf, "ERROR: Unknown opcode %.2X!", opcode);
3697 }
3698}